Попытка точно понять, что происходит, когда я использую useEffect - PullRequest
3 голосов
/ 10 января 2020

Я все еще довольно новичок в React и пытаюсь обернуть голову вокруг крючков. Сейчас я работаю с очень простым примером счетчика, используя console.log (), чтобы попытаться понять, что происходит за кулисами:

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

const Counter = () => {
    const [ count, updateCount ] = useState(0)
    console.log(count)

    useEffect(() => {
        updateCount(10)
        console.log(count) 
    }, [count])

    return (
        <div>
            <h1>Counter</h1>
            <div>
                <button onClick={() => updateCount(count-1)}>-</button>
                <span>{count}</span>
                <button onClick={() => updateCount(count+1)}>+</button>
            </div>
        </div>
    )
}

Когда я загружаю эту страницу, я вижу 0, 0 10, 10, 10 вошли в консоль. Итак, насколько я понимаю, это то, что происходит:

  1. Компонент отображается, установив значение по умолчанию count равным 0.
  2. 0 затем регистрируется на консоли, согласно строке 5
  3. useEffect всегда выполняется при первом отображении компонента, независимо от его зависимостей (верно?), поэтому он выполняет updateCount(10)
  4. Перед тем, как состояние фактически обновляется с updateCount(10), 0 записывается на консоль согласно строке 9
  5. count обновления из-за updateCount(10). Поскольку состояние изменилось, компонент перерисовывается. 10 снова регистрируется в консоли в соответствии со строкой 5
  6. Так как count указан как зависимость useEffect, а count изменился, useEffect выполняется снова.
  7. updateCount(10) вызывается снова, хотя ничего не должно делать, поскольку count уже 10.
  8. 10 снова регистрируется на консоли, как в строке 9.
  9. Это оставляет один больше 10 записывается в консоль из строки 5. Я не понимаю, почему это выполняется снова. В прошлый раз, когда вызывался useEffect, он снова установил count на 10, но, поскольку count уже был установлен на десять, компонент не должен нуждаться в повторном рендеринге, так почему строка 5 выполняется снова? ? Или компонент повторно отображается каждый раз, когда вызывается обновление состояния, независимо от того, действительно ли изменяются свойства состояния?

1 Ответ

1 голос
/ 10 января 2020

Причина, по которой вы видите, что третьи 10 вышли из системы, заключается в причуде в деталях реализации параллелизма.

https://github.com/facebook/react/issues/17474

Обычно, если setState имеет значение Строго равный компонент не будет рендериться: updateCount(prevState => prevState)

Но если есть некоторая двусмысленность в значениях состояния (из-за параллелизма), реакция должна выполнить «второй» рендеринг, чтобы убедиться, что значение состояния то же самое.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...