I am running into an issue where componentWillReceiveProps is being called to early, namely before React Redux has had the opportunity to bind a different function based on the props passed. The previous function is still bound when componentWillReceiveProps is called. Take for example this component:
const App = ReactRedux.connect((state, props) => ({
name: props.userId ? state.user.name : state.group.groupName
}), (dispatch, props) => {
return Redux.bindActionCreators({
load: props.userId ? loadUser : loadGroup
}, dispatch);
})(class extends React.Component {
componentWillMount() {
this.props.load();
}
componentWillReceiveProps() {
this.props.load();
}
render() {
return <div>Hello {this.props.name}!</div>;
}
});
We want to bind a different function to load (based on the userId prop) and a different data to props based on the property provided. Unfortunately when componentWillReceiveProps is called, the old function is still bound to load. This can be "hacked" by introducing a setTimeout in your componentWillReceiveProps that makes sure the next component is actually bound.
I've made a full example of this on jsbin: http://jsbin.com/faqama/edit?html,js,output
I'm guessing this is the result of shallowEqual checking object keys and using the same object keys for different functions? https://github.com/rackt/react-redux/blob/master/src/utils/shallowEqual.js
No, this is correct behavior.
When componentWillReceiveProps is executed, this.props still points to the old props.
However it receives nextProps as argument.
componentWillMount() {
this.props.load();
}
componentWillReceiveProps(nextProps) {
nextProps.load();
}
It's also a good idea to only call the action when IDs change because componentWillReceiveProps will be called on _any_ prop change.
componentWillMount() {
this.props.load();
}
componentWillReceiveProps(nextProps) {
if (this.props.userId !== nextProps.userId) {
nextProps.load();
}
}
Oh my goodness I feel silly, you are right! Thank you! :-D
Most helpful comment
No, this is correct behavior.
When
componentWillReceivePropsis executed,this.propsstill points to the oldprops.However it receives
nextPropsas argument.It's also a good idea to only call the action when IDs change because
componentWillReceivePropswill be called on _any_ prop change.