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.
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')
}
}