Должен ли интервал очистки / интервал быть внутри ловушки реакции 'useEffect`? - PullRequest
3 голосов
/ 20 октября 2019

Мне интересно, как правильно и наилучшим образом очистить тайм-ауты / интервалы при использовании перехватчиков React. Например, у меня есть следующий код:

import React, { useState, useEffect, useRef } from 'react';

const Test = () => {
  const id = useRef(null)
  const [count, setCount] = useState(5)
  const [timesClicked, setTimesClicked] = useState(0)

  if (!count) {
    clearInterval(id.current)
  }

  useEffect(() => {
    id.current = setInterval(() => {
      setCount(count => count -1)
    }, 1000)

    return () => {
      clearInterval(id.current)
    }
  }, [])

  const onClick = () => setTimesClicked(timesClicked => timesClicked + 1)

  return (
    <div>countdown: {count >= 0 ? count : 0}
      <hr />
      Clicked so far: {timesClicked}
      {count >= 0 && <button onClick={onClick}>Click</button>}
    </div>
  )
}

Когда count равно 0, интервал очищается в теле функции Test. В большинстве примеров, которые я видел в Интернете, интервал очищается внутри useEffect, это обязательно?

Ответы [ 2 ]

4 голосов
/ 20 октября 2019

Необходимо обязательно очистить все интервалы, прежде чем ваш компонент будет демонтирован. Интервалы никогда не исчезают автоматически, когда компоненты отключаются и для их очистки часто вызывается clearInterval внутри useEffect (() => {}, []).

Функция, восстановленная в useEffect (() => {}, []) вызывается, когда компоновка отключена.

    return () => {
      clearInterval(id.current)
    }

Вы можете увидеть, что интервалы, установленные внутри компонента, никогда не исчезают автоматически, проверив эту ссылку песочницы. https://codesandbox.io/s/cool-water-oij8s

Интервалы остаются навсегда, если не вызывается clearInterval.

1 голос
/ 20 октября 2019

setInterval - это function, которое выполняется многократно и возвращает id интервала. Когда вы звоните clearInterval с этим идентификатором, вы останавливаете этот function от повторения. Не обязательно делать это внутри определенного function, вам нужно очистить его, когда вы больше не хотите, чтобы function вызывался впоследствии. Вы можете позвонить по номеру function, который вы возвращаете в результате useEffect, если это то, что вам нужно.

...