useEffect Ошибка в setInterval и setState - PullRequest
0 голосов
/ 04 апреля 2020

Я пытался использовать функциюEact из React

useEffect(() => {
    setInterval(() => {
        const time =
            Date.parse(untilDeadline.deadline) - Date.parse(new Date());
        setuntilDeadline((prevValue) => {
            return {
                ...prevValue,
                seconds: Math.floor((time / 1000) % 60),
                minutes: Math.floor((time / 1000 / 60) % 60),
                hours: Math.floor((time / (1000 * 60 * 60)) % 24),
                days: Math.floor(time / (1000 * 60 * 60 * 24)),
            };
        });
    }, 1000);
}, []);

, это было сбой без [] в конце концов, почему?

Ответы [ 3 ]

4 голосов
/ 04 апреля 2020

Причина его сбоя в том, что вы никогда не очищаете вызов setInterval. Таким образом, каждый раз, когда компонент повторно выполняет рендеринг (например, посредством вызова setuntilDeadline), эффект запускается снова. [] Указывает на то, что эффект должен запускаться только при монтировании, а затем очищаться при размонтировании (так как это пустой массив зависимостей).

Кроме того, вы должны очистить вызов setInterval независимо от массива зависимостей. чтобы убедиться в отсутствии утечек памяти и других проблем с производительностью.

useEffect(() => {
    const intervalId = setInterval(() => {
        const time =
            Date.parse(untilDeadline.deadline) - Date.parse(new Date());
        setuntilDeadline((prevValue) => {
            return {
                ...prevValue,
                seconds: Math.floor((time / 1000) % 60),
                minutes: Math.floor((time / 1000 / 60) % 60),
                hours: Math.floor((time / (1000 * 60 * 60)) % 24),
                days: Math.floor(time / (1000 * 60 * 60 * 24)),
            };
        });
    }, 1000);
    return ()=>{
       clearInterval(intervalId);
    }
}, []);
0 голосов
/ 04 апреля 2020

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

Если вы хотите запустить эффект и очистить его только один раз (при монтировании и демонтировании), вы можете передать пустой массив ([]) в качестве второго аргумента. Это говорит React, что ваш эффект не зависит от каких-либо значений из реквизита или состояния, поэтому его не нужно повторно запускать. Это не обрабатывается как особый случай - это следует непосредственно из того, как всегда работает массив зависимостей.

Если вы передадите пустой массив ([]), реквизиты и состояние внутри эффекта всегда будут иметь свои начальные значения. ценности. Хотя передача [] в качестве второго аргумента ближе к знакомой ментальной модели componentDidMount и componentWillUnmount, обычно существуют более эффективные решения, позволяющие избежать слишком частого повторного запуска эффектов. Кроме того, не забывайте, что React откладывает запуск useEffect до тех пор, пока браузер не выполнит рисование, поэтому выполнение дополнительной работы представляет собой меньшую проблему.

https://reactjs.org/docs/hooks-effect.html

0 голосов
/ 04 апреля 2020

Пустой массив говорит, что нужно запускать это только один раз. В противном случае это может привести к бесконечному l oop повторных визуализаций.

...