Когда изменяется состояние реагирующего компонента, вызывается метод визуализации. Следовательно, для любого изменения состояния действие может быть выполнено в теле методов рендеринга. Существует ли конкретный вариант использования для обратного вызова setState?
Когда использовать обратный вызов React setState
Ответ 1
Да, так как setState
работает asynchronous
. Это означает, что после вызова setState
переменная this.state
не изменяется немедленно. так что если вы хотите выполнить действие сразу после установки состояния для переменной состояния и затем вернуть результат, обратный вызов будет полезен
Рассмотрим пример ниже
....
changeTitle: function changeTitle (event) {
this.setState({ title: event.target.value });
this.validateTitle();
},
validateTitle: function validateTitle () {
if (this.state.title.length === 0) {
this.setState({ titleError: "Title can't be blank" });
}
},
....
Приведенный выше код может работать не так, как ожидалось, поскольку переменная title
может не мутировать до того, как будет выполнена проверка. Теперь вы можете задаться вопросом, что мы можем выполнить проверку в самой функции render()
, но было бы лучше и чище, если бы мы могли обрабатывать это в самой функции changeTitle, так как это сделало бы ваш код более организованным и понятным
В этом случае обратный вызов полезен
....
changeTitle: function changeTitle (event) {
this.setState({ title: event.target.value }, function() {
this.validateTitle();
});
},
validateTitle: function validateTitle () {
if (this.state.title.length === 0) {
this.setState({ titleError: "Title can't be blank" });
}
},
....
Другой пример будет, когда вы хотите dispatch
и действие, когда состояние изменилось. Вы захотите сделать это в обратном вызове, а не в render()
как он будет вызываться каждый раз, когда происходит повторное рендеринг, и, следовательно, возможны многие такие сценарии, когда вам потребуется обратный вызов.
Другой случай - API Call
Может возникнуть ситуация, когда вам нужно сделать вызов API на основе определенного изменения состояния, если вы сделаете это в методе рендеринга, он будет вызываться при каждом изменении рендеринга onState
или из-за изменения некоторого пропуска, передаваемого onState
Child Component
.
В этом случае вы захотите использовать setState callback
для передачи обновленного значения состояния в вызов API
....
changeTitle: function (event) {
this.setState({ title: event.target.value }, () => this.APICallFunction());
},
APICallFunction: function () {
// Call API with the updated value
}
....
Ответ 2
1. usecase, который приходит мне на ум, является вызовом api
, который не должен входить в рендер, потому что он будет работать для изменения состояния each
. И вызов API должен выполняться только при специальном изменении состояния, а не в каждом рендере.
changeSearchParams = (params) => {
this.setState({ params }, this.performSearch)
}
performSearch = () => {
API.search(this.state.params, (result) => {
this.setState({ result })
});
}
Следовательно, для любого изменения состояния действие может выполняться в теле методов рендеринга.
Очень плохая практика, потому что метод render
должен быть чистым, это означает, что никакие действия, изменения состояния, вызовы api не должны выполняться, просто составьте ваше представление и верните его. Действия должны выполняться только для некоторых событий. Render - это не событие, а componentDidMount
например.
Ответ 3
this.setState({
name:'value'
},() => {
console.log(this.state.name);
});
Ответ 4
Рассмотрим вызов setState
this.setState({ counter: this.state.counter + 1 })
setState может быть вызван в асинхронной функции
Так что на this
нельзя полагаться. Если вышеупомянутый вызов был сделан внутри асинхронной функции, this
будет ссылаться на состояние компонента в тот момент времени, но мы ожидали, что это будет ссылаться на свойство внутри состояния во время вызова setState или начала асинхронной задачи. И поскольку заданием был асинхронный вызов, то это свойство могло со временем измениться. Таким образом, ненадежно использовать this
ключевое слово для ссылки на какое-либо свойство состояния, поэтому мы используем функцию обратного вызова, аргументы которой - previousState и props, что означает, что когда была выполнена асинхронная задача, и пришло время обновить состояние с помощью вызова setState, prevState теперь будет ссылаться на состояние, когда setState еще не запущен. Обеспечение надежности, что nextState не будет поврежден.
Неверный код: приведет к повреждению данных
this.setState(
{counter:this.state.counter+1}
);
Правильный код с setState с функцией обратного вызова:
this.setState(
(prevState,props)=>{
return {counter:prevState.counter+1};
}
);
Таким образом, всякий раз, когда нам нужно обновить наше текущее состояние до следующего состояния, основываясь на значении, присущем свойству прямо сейчас, и все это происходит асинхронно, рекомендуется использовать setState в качестве функции обратного вызова.