Search code examples
javascriptreactjsgetderivedstatefromprops

Returning state after API call inside getDerivedStateFromProps


I have a react component that receives props for filtering from its parent. When the parent props change I use getDerivedStateFromProps in the child in the following code:

static getDerivedStateFromProps(props, state) {
  if (props.filter === null) {
     return state;
  }

  const { name, description } = props.filter;

  ApiService.get("cards", { name: name, description: description })
    .then(response => {
      console.log("get request returned ", response.data);

      return { cards: response.data };
    }
  );
}

in the console the response.data log is the approriate array of objects. However the state does not update and the rendering function still uses the old cards array and not the one that was received from the ApiService response. How do I make it so the cards array updates properly so that on the next render it will show the filtered cards?


Solution

  • getDerivedStateFromProps is not the correct lifecycle hook for this. You'll need to put the fetching code in componentDidMount and componentDidUpdate, and use this.setState once the data is available.

    class Example extends React.Component {
      constructor(props) {
        super(props); 
        this.state = {
          cards: null,
        }
      }
    
      componentDidMount() {
        this.loadData();
      }
    
      componentDidUpdate(prevProps) {
        if (this.props.filter !== prevProps.filter) {
          this.loadData();
        }
      }
    
      loadData() {
        const { name, description } = this.props.filter;
    
        ApiService.get("cards", { name: name, description: description })
          .then(response => {
            this.setState({ cards: response.data });
          });
      )
    
      render() {
        if (!this.state.cards) {
          return <div>Loading...</div>
        }
    
        return (
          // some jsx using the cards
        )
      }
    }