otong
otong

Reputation: 1545

React not rendering after props (list of object) is updated

I have state in redux (a list of object), and I have an action to add blank object to the list. But whenever I dispatching the action React doesn't response to the changed props. I tried to log console in componentDidUpdate, shouldComponentUpdate it doens't log a changed props.

this is the action

function addNewBlankObject() {
  const newBlankObject= {
    field1: "",
    field2: ""
  }
  return {type:'ADD_BLANK_OBJECT', newBlankObject: newBlankObject}
}

this is the reducer

case 'ADD_BLANK_OBJECT':
      var listOfObject = state.listOfObject;
      listOfObject.push(action.newBlankObject);
      return state;

this is the redux props mapper

function mapStateToProps(state) {
  console.log(state.listOfObject); //check if state updated
  const listOfObject = state.listOfObject;
  return {
    listOfObject,
  }
}

export default connect(mapStateToProps)(AComponent);

I tried to log the props in above method, it does update the state, a blank object is added to the list, thus the props is changed right? why React doesn't response? Is it because the state is a array?

Upvotes: 1

Views: 84

Answers (3)

RIYAJ KHAN
RIYAJ KHAN

Reputation: 15292

The state reference it not getting changed.Its remain same. Redux do shallow comparison to decide to update the state or not.

State update in reducers should be like this.

case 'ADD_BLANK_OBJECT':

      return [
        ...state.listOfObject,action.newBlankObject
      ]

Please find more here

Upvotes: 2

xadm
xadm

Reputation: 8418

Return new object in reducer, not mutate existing one.

Upvotes: 1

jsDevia
jsDevia

Reputation: 1292

You should use componentWillReceiveProps, always put the redux state which has updates in the component state and with componentWillReceiveProps, update the state.

class AComponent extends Component {
    constructor(props, context) {
        super(props, context);
        this.state = {
            listOfObject: props.listOfObject
        };
    }

    componentWillReceiveProps(nextProps) {
        let state = this.state;
        state.listOfObject = nextProps.listOfObject;
        this.setState({ state });
    }

    render() {
        return (
            <div></div>
        );
    }
}

function mapStateToProps(state) {
    console.log(state.listOfObject); //check if state updated
    const listOfObject = state.listOfObject;
    return {
      listOfObject,
    }
  }

  export default connect(mapStateToProps)(AComponent);

Upvotes: 0

Related Questions