infinite loop when dispatching in componentWillReceiveProps
Solution 1
Your componentWillReceiveProps
is in an infinite loop because calling fetchUser
will dispatch an action that will update the Props.
Add a comparison to check if the specific prop changes before dispatching the action. EDIT:
In React 16.3+ componentWillReceiveProps
will be slowly deprecated.
It is recommended to use
componentDidUpdate
in place ofcomponentWillReceiveProps
componentDidUpdate(prevProps) {
if (this.props.params.username !== prevProps.params.username) {
dispatch(fetchUser(username));
}
}
Solution 2
Try adding a condition to compare the props. If your component needs it.
componentWillRecieveProps(nextProps){
if(nextProps.value !== this.props.value)
dispatch(action()) //do dispatch here
}
Solution 3
If you have react routes with some path params like profile/:username, You can simply compare the props.location.pathname
componentWillReceiveProps(nextProps){
if(nextProps.location.pathname !== this.props.location.pathname){
dispatch()
}
}
hazmah0
Updated on June 08, 2022Comments
-
hazmah0 almost 2 years
I have a Profile component that is loaded by react-router (path="profile/:username") and the component itself looks like this:
... import { fetchUser } from '../actions/user'; class Profile extends Component { constructor(props) { super(props); } componentDidMount() { const { username } = this.props; this.fetchUser(username); } componentWillReceiveProps(nextProps) { const { username } = nextProps.params; this.fetchUser(username); } fetchUser(username) { const { dispatch } = this.props; dispatch(fetchUser(username)); } render() {...} } export default connect((state, ownProps) => { return { username: ownProps.params.username, isAuthenticated: state.auth.isAuthenticated }; })(Profile);
And the fetchUser action looks like this (redux-api-middleware):
function fetchUser(id) { let token = localStorage.getItem('jwt'); return { [CALL_API]: { endpoint: `http://localhost:3000/api/users/${id}`, method: 'GET', headers: { 'x-access-token': token }, types: [FETCH_USER_REQUEST, FETCH_USER_SUCCESS, FETCH_USER_FAILURE] } } }
The reason I added componentWillReceiveProps function is to react when the URL changes to another :username and to load that users profile info. At a first glance everything seems to work but then I noticed while debugging that componentWillReceiveProps function is called in a infinite loop and I don't know why. If I remove componentWillReceiveProps then the profile doesn't get updated with the new username but then I have no loops problem. Any ideas?
-
hazmah0 about 8 yearsI understand now. The reducer for FETCH_USER_SUCCESS stored som user data which my Profile component was connecting over (which I forgot to add to my code above when writing the question). So the flow was componentWillReceiveProps --> dispatcher --> reducer updates data that Profile connects on --> componentWillReceiveProps is called again and it all starts over. I think I will need to move the code for route changes somewhere else to avoid this loop. Thanks!