React Native state variables not getting updated from props

Viewed 125

I'm passing 3 props - numLikes, id and userLiked to my class and I want to set my state variables initially before any render occurs. Ideally, the values of state variables should be equal to their props counterparts but this isn't the case.

This is my code:

export default class LikeButton2 extends Component {
  constructor(props) {
    super(props);
    this.state = {
      numLikes: props.numLikes,
      id: props.id,
      userLiked: props.userLiked,
      isloading: true,
    };
  }
 //....
}

I used React Native Debugger to check for the variable values and the variables "numLikes" and "userLiked" were not getting updated. Attached is the proof for the same:

enter image description here

I also tried using spread syntax. This is my code:

export default class LikeButton2 extends Component {
  constructor(props) {
    super(props);
    this.state = {
      ...props,
      isLoading: true,
    };
  }
 //....
}

Although this also resulted in undesired values for the state variables. Proof for this in RN Debugger:

React Native Debugger output - 2

How can I correctly update the values?

1 Answers

In this exemple, when the component is mounted to be displayed, the state is set to be equal to the props. The constructor is only called at that time.

After that, if the props change, the state won't be updated to match them. If you want your state to be updated when the props change, you need to use the method ComponentDidUpdate:ComponentDidUpdate(prevProps,prevState).

It will be called every time the props or the state change. You can then compare the current props (this.props) and the previous props (prevProps) to set your state accordingly.

If you just want to use your props as they are you can just use this.props, it will always reflect the value you give to the component.

If I have <Component number={myNumber}/> somewhere in the code, Component will rerender every time myNumber changes, and the value this.props.myNumber in Component will be accurate.

export default class ComponentTest extends Component {
  constructor(props) {
    super(props);
  }
  render() {
     return <div>{this.props.number}</div>
  }
}
Related