Почему мой компонент React обновляется автоматически? - PullRequest
1 голос
/ 20 марта 2020

У меня есть простой компонент React, и когда я проверяю консоль, то, что я зарегистрировал, появляется 3 раза.

Журнал Load APP поступает из моего основного компонента App.js и Load New из компонента, отображаемого с помощью Навигации в App.js: FasList.js.

Почему я вижу 3 регистрируется, когда я только один раз регистрируюсь в моем компоненте?

Log output

Я провел второй тест с журналом в useEffect:

Second Log output with useEffect

Вот код в App.hjs:

    console.log('APP');

    useEffect(() => {
        fetchAuthStatus();
        console.log("I'm in useEffect");
    }, []);

Имеет ли повторяющийся вывод журнала какое-либо отношение к тому, как работает React ?

Согласно второму тесту, компонент рендерит только 1 раз, но все равно 3 APP log

Вот рабочий пример проблемы с моими 2 компонентами: https://stackblitz.com/edit/logs-output-demo

Ответы [ 2 ]

3 голосов
/ 20 марта 2020

Тело вашей функции компонента запускается каждый раз, когда компонент визуализируется. Ваш компонент визуализируется каждый раз, когда React считает это необходимым, но обычно один раз при первоначальном добавлении на страницу, а затем снова при каждом изменении его состояния. (Несколько изменений состояния, выполняемых одновременно, обычно приводят только к одному рендеру, но если между ними есть разрыв, рендеринг будет выполняться после каждого.)

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

Вот простой пример:

const {useState, useEffect} = React;

const Example = () => {
    const [counter, setCounter] = useState(0);
    const [flag, setFlag] = useState(false);

    // Runs after initial render, then again every time `flag` changes
    useEffect(() => {
        console.log(`useEffect #1 ran, flag = ${flag}`);
    }, [flag]);

    // Runs after initial render, then every time `flag` or
    // `counter` changes
    useEffect(() => {
        console.log(`useEffect #2 ran, flag = ${flag}, counter = ${counter}`);
    }, [flag, counter]);
    
    // Runs after initial render only
    useEffect(() => {
        console.log(`useEffect #3 ran`);
    }, []);
    
    return (
        <div>
            <input type="button" value="Increment" onClick={() => setCounter(c => c + 1)} />
            <input type="button" value="Flip Flag" onClick={() => setFlag(f => !f)} />
        </div>
    );
};

ReactDOM.render(<Example />, document.getElementById("root"));
<div id="root"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.12.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.12.0/umd/react-dom.production.min.js"></script>

Вы можете найти эту статью Дана Абрамова полезной. В нем подробно рассказывается о том, как рендерит React, в контексте объяснения useEffect (но это полезное чтение, даже отдельно от понимания useEffect).

1 голос
/ 20 марта 2020

Вы изменяете состояние еще 1 раз с помощью метода fetchAuthStatus(), поэтому происходит повторный рендеринг. Это не означает, что DOM изменяется дважды. Я думаю, что ваш код действителен.

...