React Hooks - используйте пожары Effect, хотя состояние не изменилось - PullRequest
0 голосов
/ 28 февраля 2019

Я установил эффект внутри моего компонента, который меняет представление, если изменяется другой атрибут состояния.Но по какой-то причине, когда компонент монтируется, эффект запускается, даже если значение detailIndex не изменилось.

const EventsSearchList = () => {
    const [view, setView] = useState('table');
    const [detailIndex, setDetailIndex] = useState(null);

    useEffect(() => {
        console.log('onMount', detailIndex);
        // On mount shows "null"
    }, []);


    useEffect(
        a => {
            console.log('Running effect', detailIndex);
            // On mount shows "null"!! Should not have run...
            setView('detail');
        },
        [detailIndex]
    );

    return <div>123</div>;

};

Почему это происходит?

ОБНОВЛЕНИЕ : В случае, если неясно, что я пытаюсь запустить эффект при обновлении компонента, потому что detailIndex изменяется.НЕ когда он монтируется.

Ответы [ 2 ]

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

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

Дополнительная информация: https://reactjs.org/docs/hooks-effect.html

Источник:

Опытные разработчики JavaScript могут заметить, что функция, передаваемая в useEffect, будет отличаться для каждого рендера.[...] Вы можете указать React пропустить применение эффекта, если определенные значения не изменились между повторными рендерингами.Для этого передайте массив в качестве необязательного второго аргумента в useEffect: [...]

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

useEffect всегда запускается после первоначального рендеринга.

С документы :

Запускается ли useEffect после каждого рендеринга? Да!По умолчанию он запускается как после первого рендера, так и после каждого обновления.(Позже мы поговорим о том, как это настроить.) Вместо того, чтобы думать в терминах «монтирования» и «обновления», вам может показаться, что вам будет легче думать, что эффекты происходят «после рендеринга».React гарантирует, что DOM был обновлен к моменту запуска эффектов.

В отношении вашего кода следующее будет выполняться только один раз (поскольку вы предоставляете пустой массив в качестве второго аргумента для useEffect):

useEffect(() => {
  console.log('onMount', detailIndex);
  // On mount shows "null" -> since default value for detailIndex is null as seen above
  // const [detailIndex, setDetailIndex] = useState(null);
}, []);

И это будет работать только при изменении detailIndex (попробуйте позвонить setDetailIndex в течение предыдущего useEffect):

useEffect(() =>
  // ... effect code
}, [detailIndex]);

ссылка API-интерфейса ловушки useEffect

...