Answer the question
In order to leave comments, you need to log in
React + Redux. Proper use of QueryString and componentWillReceiveProps?
Dear Colleagues, Need help with redux "recursiveness" issue.
Description of the problem:
The essence is that the component receives props
from react-router
and componentWillMount
loads the first page of records. Everything is great at this stage.
Next, we filter / sort the data or use pagination and send the user to a new url with a changed qs (example /news/list?page=2). At this stage, logically, you need to use componentWillReceiveProps
, since the component has remained the same, but new data has arrived. If we execute inside this method dispatch(actions.чтонибудь())
, then we will receive data in props and here recursion occurs.
react-router -> componentWillReceiveProps -> dispatch -> componentWillReceiveProps -> dispatch -> ...
const { params } = nextProps;
if (params.page != this.props.page || params.page_size != this.props.page_size || params.order != this.props.order || ...) {
Answer the question
In order to leave comments, you need to log in
In this situation, the component should be connected to redux via connect. Then you will have the opportunity to see what is already loaded and what is not.
If you have some complex logic - I would suggest making an isLoaded flag and passing it as props to the component. Then, in the componentWillReceiveProps method, you can check if this flag is clear by calling the load function.
But specifically in this case, it's better to do what was done in the official real-world-example example : check if the page number has changed and only in this case dispatch the actions.
UPD1. Code example:
// MyComponent
import shallowequal from 'shallowequal';
export default class MyComponent {
static propTypes = {
items: PropTypes.array.isRequired,
filtres: PropTypes.object.isRequired, // <-- тут можно собрать все фильтры
};
componentWillReceiveProps(nextProps) {
if(!shallowequal(this.props.filtres, nextProps.filtres)) {
loadData(filtres);
};
}
}
// MyComponentContainer
import MyComponent from './MyComponent';
function mapState(state, ownProps) {
return {
items: applyFiltres(state.someReducer.someItems),
filtres: ownProps.location.query, // <--- как пример
};
}
export default connect(mapState)(MyComponent);
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question