Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Updating Redux state does not trigger componentWillReceiveProps

Tags:

I'm trying to validate the login information. After making sure the login is valid I want to fire a new route. I pass the state.loginReducer.login as props. When I handle the submit event, an action is dispatched, changing the global login state.

Shouldn't ComponentWillReceiveProps be fired in this case? since the props changed?. Is there a better way to implement this functionality?

handleSubmit (evt) {     const {         dispatch,         login     } = this.props;      dispatch(actions.doLogin(value.login)); }  ComponentWillReceiveProps (nextprops) {     const {         login     } = this.nextProps;      if (login != null) {         history.pushState({}, '/account');     } }  function mapStateToProps (state) {     return {         login: state.loginReducer.login     } }  export default connect(mapStateToProps)(Login); 
like image 352
João Lima Avatar asked Oct 24 '15 18:10

João Lima


People also ask

What happens when Redux state changes?

The only way to update a state inside a store is to dispatch an action and define a reducer function to perform tasks based on the given actions. Once dispatched, the action goes inside the reducer functions which performs the tasks and return the updated state to the store. This is what Redux is all about.

When mapStateToProps is called?

If your mapStateToProps function is declared as taking two parameters, it will be called whenever the store state changes or when the wrapper component receives new props (based on shallow equality comparisons).

Why mapStateToProps?

As the first argument passed in to connect , mapStateToProps is used for selecting the part of the data from the store that the connected component needs. It's frequently referred to as just mapState for short. It is called every time the store state changes.

What is ownProps in Redux?

The mapStateToProps(state, ownProps) is specified as the first argument of connect() call and its ownProps parameter receives the props object of the wrapper component. If the ownProps parameter is not present, React Redux skips calling the function at the props change.


1 Answers

If state.loginReducer.login changes, then componentWillReceiveProps will get triggered. If you believe your reducer is returning a new state, and componentWillReceiveProps is not being triggered, make sure that the new state is immutable. Returning the same state reference thats passed to the reducer won't work.

From https://github.com/reactjs/redux/blob/master/docs/Troubleshooting.md

This is wrong:

function todos(state = [], action) {   switch (action.type) {   case 'ADD_TODO':     // Wrong! This mutates state     state.push({       text: action.text,       completed: false     });   case 'COMPLETE_TODO':     // Wrong! This mutates state[action.index].     state[action.index].completed = true;   }    return state; } 

This is right:

function todos(state = [], action) {   switch (action.type) {   case 'ADD_TODO':     // Return a new array     return [...state, {       text: action.text,       completed: false     }];   case 'COMPLETE_TODO':     // Return a new array     return [       ...state.slice(0, action.index),       // Copy the object before mutating       Object.assign({}, state[action.index], {         completed: true       }),       ...state.slice(action.index + 1)     ];   default:     return state;   } } 
like image 136
Nathan Hagen Avatar answered Oct 21 '22 12:10

Nathan Hagen