С Реагировать на документы :
Если вы знакомы с методами жизненного цикла класса React, вы можете подумать
использования Effect Hook как componentDidMount, componentDidUpdate и
компонентWillUnmount в сочетании.
Под этим высказыванием они подразумевают:
componentDidMount является своего рода useEffect(callback, [])
componentDidUpdate является своего рода useEffect(callback, [dep1, dep2, ...])
- массив deps сообщает React: "если один из deps изменяется, запустите обратный вызов после рендеринга" .
componentDidMount + componentDidUpdate является своего рода useEffect(callback)
componentWillUnmount является сортировкой возвращенной функции из обратного вызова:
useEffect(() => {
/* some code */
return () => {
/* some code to run when rerender or unmount */
}
)
С помощью Дан Абрамов формулирует из своего блога и некоторые мои собственные добавления:
Хотя вы можете использовать эти крючки, это не является точным эквивалентом. В отличие от componentDidMount
и componentDidUpdate
, он будет захватывать реквизита и состояния. Так что даже внутри обратных вызовов вы увидите реквизиты и состояние конкретного рендера (что означает componentDidMount
исходные реквизиты и состояние). Если вы хотите увидеть что-то «последнее», вы можете написать это в ссылку. Но обычно есть более простой способ структурировать код, чтобы вам не пришлось это делать.
Возвращаемая функция, предполагающая альтернативу componentWillUnmount
, также не является точным эквивалентом, поскольку функция будет запускаться каждый раз, когда компонент будет перерисовываться, и когда компонент будет размонтирован.
Имейте в виду, что ментальная модель для эффектов отличается от жизненных циклов компонентов, и попытка найти их точные эквиваленты может сбить вас с толку больше, чем помочь. Чтобы стать продуктивным, вам нужно «мыслить эффектами», и их ментальная модель ближе к реализации синхронизации, чем к реагированию на события жизненного цикла.
Пример из блога Дэна:
function Counter() {
const [count, setCount] = useState(0);
useEffect(() => {
setTimeout(() => {
console.log(`You clicked ${count} times`);
}, 3000);
});
return (
<div>
<p>You clicked {count} times</p>
<button onClick={() => setCount(count + 1)}>
Click me
</button>
</div>
);
}

Если мы используем реализацию класса:
componentDidUpdate() {
setTimeout(() => {
console.log(`You clicked ${this.state.count} times`);
}, 3000);
}

this.state.count
всегда указывает на последний счет, а не тот, который принадлежит определенному рендеру.