При изменении состояния реагирующего компонента вызывается метод рендеринга. Следовательно, для любого изменения состояния действие может быть выполнено в теле методов рендеринга. Есть ли конкретный вариант использования для обратного вызова setState?
191
render()
вместо этого вы включите эту функцию , она будет запускаться каждый раз при обновлении ЛЮБОГО состояния, что, вероятно, не то, что вам нужно. Это также сделает ваш код менее читабельным и логичным.Ответы:
Да, так как
setState
работает такимasynchronous
образом. Это означает , что после вызоваsetState
вthis.state
переменной не сразу изменилось. так что если вы хотите выполнить действие сразу после установки состояния для переменной состояния, а затем вернуть результат, обратный вызов будет полезенРассмотрим пример ниже
Приведенный выше код может работать не так, как ожидалось, поскольку
title
переменная может не мутировать до того, как будет выполнена проверка. Теперь вы можете задаться вопросом, что мы можем выполнить проверку в самойrender()
функции, но было бы лучше и чище, если бы мы могли обрабатывать это в самой функции changeTitle, поскольку это сделало бы ваш код более организованным и понятнымВ этом случае обратный вызов полезен
Другим примером будет, когда вы хотите,
dispatch
и действия, когда состояние изменилось. вы захотите сделать это вrender()
обратном вызове, а не в том, как он будет вызываться при каждом повторном рендеринге, и, следовательно, возможны многие такие сценарии, когда вам потребуется обратный вызов.Еще один случай
API Call
Может возникнуть ситуация, когда вам нужно сделать вызов API на основе определенного изменения состояния, если вы сделаете это в методе рендеринга, он будет вызываться при каждом
onState
изменении рендеринга или потому, что какой-то пропущенный элемент передаетсяChild Component
измененному.В этом случае вы захотите использовать a
setState callback
для передачи обновленного значения состояния в вызов APIисточник
if (this.title.length === 0) {
должно бытьthis.state.title.length
, верно?setState(state => state.title.length ? { titleError: "Title can't be blank" } : null)
и изменения будут складываться. Двойной рендеринг не требуется.источник
1. Случай использования, который приходит мне в голову, - это
api
вызов, который не должен входить в рендер, потому что он будет работать дляeach
изменения состояния. И вызов API должен выполняться только при специальном изменении состояния, а не при каждом рендеринге.Очень плохая практика , потому что
render
-метод должен быть чистым, это означает, что никакие действия, изменения состояния, вызовы API не должны выполняться, просто составьте свое представление и верните его. Действия должны выполняться только для некоторых событий. Рендер это не событие, аcomponentDidMount
например.источник
Рассмотрим вызов setState
IDEA
Таким образом, вы не можете положиться на
this
. Если вышеупомянутый вызов был сделан внутри асинхронной функции, этоthis
будет ссылаться на состояние компонента в этот момент времени, но мы ожидали, что это будет ссылаться на свойство внутри состояния во время вызова setState или начала асинхронной задачи. И поскольку заданием был асинхронный вызов, то это свойство могло со временем измениться. Таким образом, это ненадежно использоватьthis
ключевое слово для ссылки на какое-либо свойство состояния, поэтому мы используем функцию обратного вызова, аргументы которой - previousState и props, что означает, что когда была выполнена асинхронная задача и пришло время обновить состояние с помощью вызова setState, prevState теперь будет ссылаться на состояние, когда setState еще не началось. Обеспечение надежности, что nextState не будет поврежден.Неверный код: приведет к повреждению данных
Правильный код с setState с функцией обратного вызова:
Таким образом, всякий раз, когда нам нужно обновить наше текущее состояние до следующего состояния, основываясь на значении, присущем свойству прямо сейчас, и все это происходит асинхронно, хорошей идеей будет использование setState в качестве функции обратного вызова.
Я попытался объяснить это в codepen здесь CODE PEN
источник