0

I have state like below:

this.state = {
data: [ .... ]
misc: [  .... ]
}

I have button when clicked it will fetch data.

the data will be fetched using axios and then setState is used to replace the this.state.data

Then as per reactjs render will be called every time you setState to re-render the component if there are changes.

After this.state.data is updated, and rendering is complete i want to run a function.

I dont want to run the function when misc is updated. I only want to update when data is updated

How to run a function after render only when this.state.data is changed

4 Answers 4

1

If you want to restrict rendering on particular state change then just check for that state and return false else return true like:

shouldComponentUpdate(nextProps, nextState) {

     if(this.state.misc != nextState.misc) {
          return false
     }
     return true
}
Sign up to request clarification or add additional context in comments.

Comments

1

If I understood your question correctly you're talking about the use of lifecycle methods...

You should do your data fetching (ajax via axios or the native fetch api) in the componenetDidMount lifecycle hook

Something like this:

componentDidMount() {
  this.setState({ isLoading: true });

  axios
    .get(url)
    .then(result => this.setState({ data: result.data, isLoading: false }))
    .catch(error => this.setState({ error, isLoading: false }));
}

And your updating in componentDidUpdate More info here: https://reactjs.org/docs/state-and-lifecycle.html

Comments

1

You could use componentDidUpdate (https://reactjs.org/docs/react-component.html#componentdidupdate). This is a lifecycle event that triggers every time the component updates, so you can check if the previous state of data is different than the current state. I'm assuming data is an array of objects, so to compare them you'll either have to use something to compare like _.isEqual from lodash, or what I've included below will work.

componentDidUpdate(prevProps, prevState) {
  if(JSON.stringify(prevState.data) !== JSON.stringify(this.state.data)) {
    // Execute your code
  }
}

Comments

0

You need to use componentDidMount(), which will be called after a component is mounted (first render) and componentDidUpdate(), which will be called immediately after updating occurs (but not for the initial render).

componentDidUpdate takes 3 parameters: prevProps, prevState and snapshot. In your case, you can compare prevState.data against this.state.data to know whether data has been updated:

class Main extends React.Component {

  constructor(props) {
    super(props);
    
    this.counter = 0;
    
    this.state = {
      data: [],
      misc: 'foo',
    };
    
    this.changeData = this.handleChangeData.bind(this);
    this.changeMisc = this.handleChangeMisc.bind(this);
  }
  
  componentDidMount() {
    console.log('componentDidMount!');
  }
  
  componentDidUpdate(prevProps, prevState) {
    if (prevState.data !== this.state.data) {
      console.log('componentDidUpdate and data has changed!');
    }    
  }
  
  handleChangeData() {
    this.setState({
      data: [...this.state.data, this.counter++].slice(-10),
    });
  }
  
  handleChangeMisc() {
    this.setState({
      misc: this.state.misc === 'foo' ? 'bar' : 'foo',
    });
  }
  
  render() {
    return(
      <div>
        <button onClick={this.changeData}>Change data</button>
        <button onClick={this.changeMisc}>Change misc</button>

        <pre>DATA = { this.state.data.join(', ') }</pre>
        <pre>MISC = { this.state.misc }</pre>
      </div>
    );
  }
}

ReactDOM.render(<Main />, document.getElementById('app'));
.as-console-wrapper {
  max-height: 106px !important;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>

<div id="app"></div>

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.