Irene Li
Irene Li

Reputation: 219

State not updating when receiving new props (ReactJS)

I'm new to React. I'm stuck on this, would really appreciate some help!

A parent component will pass an array into this child component. When I console.log(this.props.repairs) it shows me an array of 4. I am trying to update this.state.sortedDataList whenever the array of repairs is passed in. The console.log(this.state) is still showing sortedDataList as an empty array.

What am I doing wrong? Thanks so much, appreciate any help.

class Repairs extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      sortedDataList: []
    };
  }

  componentWillReceiveProps(nextProps) {
    if(this.props != nextProps) {
      this.setState({
        sortedDataList: this.props.repairs
      });
    }
  }

  render() {
    console.log(this.props);
    console.log(this.state);

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

Upvotes: 13

Views: 15828

Answers (3)

Irene Li
Irene Li

Reputation: 219

Never mind, found my silly mistake! If anyone else gets stuck on this in the future...

componentWillReceiveProps(nextProps) {
  if(this.props != nextProps) {
    this.setState({
      sortedDataList: nextProps.repairs
    });
  }
}

Upvotes: 8

Shubham Khatri
Shubham Khatri

Reputation: 282120

componentWillReceiveProps isn't called on the first render. That is the reason that you don't see any update in the state

From the React Docs:

"Invoked when a component is receiving new props. This method is not called for the initial render."

If you want to make the change only first time you can make use of componentWillMount lifecycle function and update the state. On subsequent changed you componentWillReceiveProps will be called.

class Repairs extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      sortedDataList: []
    };
  }

  componentWillMount() {
   
      this.setState({
        sortedDataList: this.props.repairs
      }, () => console.log(this.state.sortedDataList));
    
  }
   componentWillReceiveProps(nextProps) {
    if(this.props != nextProps) {
      this.setState({
        sortedDataList: nextProps.repairs
      });
    }
  }

  render() {
    console.log("r",this.props);
    console.log("r",this.state);

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

class App extends React.Component {
  render() {
    var arr = ["1", "2", "3"];
    return (
      <div >
        <Repairs repairs={arr}/>
      </div>
    )
  }
}
ReactDOM.render(<App/>, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react-dom.min.js"></script>
<div id="app"></div>

Upvotes: 3

Jayce444
Jayce444

Reputation: 9073

In your constructor

this.state = {
  sortedDataList: []
};

You initially set state to an empty array, so on first render it'll be empty. Then, whenever the props are changed, it'll get updated via componentWillReceiveProps().

As Shubham said, componentWillReceiveProps() isn't called on the first render. If you want the state to reflect the props right from the first render, you'd have to put it in the constructor like so:

this.state = {
  sortedDataList: this.props.repair
};

Upvotes: 0

Related Questions