Search code examples
reactjsfetchpreact

Preact/React and setting state after fetch


My calls to setState are doing nothing in the then of a fetch.

The class is declared like this:

export default class QuestionHolder extends React.Component<Props, State> {
  constructor(props: Props) {
    super(props)
    this.state = {
      completed:            false,
      revealAnswer:         false,
      selectedAlternative:  undefined,
      submitting:           false,
      explanation:          'philosophy',
    }

    console.log('props', props)
    console.log('state', this.state)
  }
    fetch(`/questions/${this.question.id}/submit`, {
      method:   'POST',
      headers:  {
        'Content-Type': 'application/json',
        },
        body: JSON.stringify({
          chosen:       this.state.selectedAlternative.id,
          }),
      })
      .then(response => response.json())
      .then(data => {
        console.log('data', data)
        console.log('state before', this.state)
        this.setState({
          explanation: 'phil says so'
        })
        console.log('state after', this.state)
      })

The fetch works fine (returns data and a 200 etc etc - this is legacy code I am updating), but the calls to console.log show that this.state never changes from the values set in the constructor.


Solution

  • State updates may be asynchronous and reading it immediately after setting it will not provide the correct result.

    The right place to check for state change is either to pass callback as second argument to setState method

      this.setState({
          explanation: 'phil says so'
        },() => {
          console.log('Set the explanation state successfully')
        })
    

    or using componentDidUpdate lifecycle method.

    componentDidUpdate(prevProps, prevState){
      if (prevState.explanation !== this.state.explanation) {
        console.log('Set the explanation state successfully')
      }
    }