1
votes

I'm building a react native app and using redux to handle the state. I am running into a situation where one of my containers is not updating immediately when the redux state is changed.

Container:

...
class ContainerClass extends Component<Props, State> {
    ...
    componentWillReceiveProps(nextProps: Object) {
        console.log('WILL RECEIVE PROPS:', nextProps);
    }
    ...
    render() {
        const { data } = this.props;
        return <SubComponent data={data} />
    }
}

const mapStateToProps = (state) => ({
    data: state.data
};

export default connect(mapStateToProps)(ContainerClass);

Reducer:

...
export default function reducer(state = initalState, action) => {
    switch(action.type) {
        case getType(actions.actionOne):
            console.log('SETTING THE STATE');
            return { ...state, data: action.payload };
        ...
    ...
...

In a different random component, I am dispatching a call with the actionOne action, which I confirm prints out the relevant console.log. However, the console.log in the componentWillReceiveProps in the container is not printed.

The component that dispatches the call is a modal that has appeared over the Container, and closes automatically after the call is dispatched and the state is updated. What is weird is that although the Container isn't updated immediately, if I navigate to a different page and then back to the Container page, the state is in fact updated.

EDIT: Initial state is:

const initialState: Store = {
    data: []
}

And the way I dispatch is in a different component which gets called as a new modal (using react-native-navigation) from Container:

fnc() {
    ...
    setData(data.concat(newDatum));
    ...
}

Where setData and data are the redux dispatch action and the part of the store respectively that is passed in on props from the Container (which has setData and data through mapStateToProps shown above and a mapDispatchToProps which I didn't show).

4
Maybe your actual code is different, but you have an unclosed paren in mapStateToPropsKai
@Infamous911: Please share the code how you dispatch the actionIsaac
Please share your state structure in the state = initalStateRIYAJ KHAN
@RIYAJKHAN addedInfamous911
@Isaac added aboveInfamous911

4 Answers

1
votes

I solved my problem by updating from react-native v0.56 to v0.57. Apparently there was a problem with react-redux v6 working properly in the react-native v0.56 environment.

0
votes

Assuming you're using a recent version of React, componentWillReceiveProps is actually deprecated:

Using this lifecycle method often leads to bugs and inconsistencies

You can't really rely on that lifecycle hook in a number of situations. You may want to look at a slightly different approach with componentDidUpdate instead.

0
votes

I think more important is to get the value after changing in state of redux rather than in which lifecycle you are getting the value . so for getting the value you can use subscribe method of redux in componentDidMount

store.subscribe( ()=> {
  var updatedStoreState = store.getState();
})
0
votes

I believe that getDerivedStateForProps would solve your problem.

static getDerivedStateFromProps(nextProps, prevState) {
  if(nextProps.data !== prevState.data) {
    //Do something
  } else {
    //Do something else
  }
}

You would check the state from the redux against the state from your component and then act accordingly.

Also, some info from the documentation that you might consider before using this method:

1. getDerivedStateFromProps is invoked right before calling the render method, both on the initial mount and on subsequent updates.

2. This method exists for rare use cases where the state depends on changes in props over time.

3. If you need to perform a side effect (for example, data fetching or an animation) in response to a change in props, use componentDidUpdate lifecycle instead.

You can read more at: https://reactjs.org/docs/react-component.html#static-getderivedstatefromprops