Могу ли я установить состояние внутри ловушки useEffect? - PullRequest
0 голосов
/ 11 декабря 2018

Допустим, у меня есть какое-то состояние, которое зависит от какого-то другого состояния (например, когда меняется A, я хочу изменить B).

Уместно ли создавать ловушку, которая наблюдает за A и устанавливает B внутри ловушки useEffect?

Будут ли эффекты каскадироваться так, что, когда я нажму кнопку, первый эффект сработает, из-за чего изменится b, а второй эффект сработает до следующего рендера?Есть ли какие-либо недостатки в производительности для структурирования кода, подобного этому?

let MyComponent = props => {
  let [a, setA] = useState(1)
  let [b, setB] = useState(2)
  useEffect(
    () => {
      if (/*some stuff is true*/) {
        setB(3)
      }
    },
    [a],
  )
  useEffect(
    () => {
      // do some stuff
    },
    [b],
  )

  return (
    <button
      onClick={() => {
        setA(5)
      }}
    >
      click me
    </button>
  )
}

Ответы [ 3 ]

0 голосов
/ 28 февраля 2019

Использование setState внутри useEffect создаст бесконечный цикл, который, скорее всего, вы не захотите вызывать.

useEffect вызывается после каждого рендера и когда setState используется внутриэто приведет к повторной визуализации компонента, которая будет вызывать useEffect и т. д. и т. п.

Единственный случай, когда использование useState внутри useEffect не вызовет бесконечный цикл, этокогда вы передаете пустой массив в качестве второго аргумента useEffect, как useEffect(() => {....}, []), что означает, что функция эффекта должна вызываться один раз: только после первого монтирования / рендеринга.

0 голосов
/ 11 июля 2019

useEffect может зацепить определенную опору или состояние.Итак, чтобы избежать перехвата бесконечного цикла, нужно связать некоторую переменную или состояние с эффектом

, например.

useEffect(myeffect, [])

Вышеупомянутый эффект сработает только после рендеринга компонента.это похоже на жизненный цикл componentDidMount

const [something, setSomething] = withState(0)
const [myState, setMyState] = withState(0)
useEffect(() => {
  setSomething(0)
}, myState)

. Вышеупомянутый эффект вызовет только мое состояние, изменившееся. Это похоже на componentDidUpdate, за исключением того, что не каждое изменяющееся состояние будет запускать его

. ссылка

0 голосов
/ 11 декабря 2018

Эффекты всегда выполняются после завершения фазы рендеринга, даже если вы установите setState внутри одного эффекта, другой эффект прочитает обновленное состояние и выполнит действие только после фазы рендеринга.

Сказав, что, вероятно, лучше выполнить оба действия с одинаковым эффектом, если только не существует вероятность, что b может измениться по причинам, отличным от changing a, и в этом случае вы также захотите выполнить то же самоелогика

...