useEffect вызывается дважды - PullRequest
1 голос
/ 07 апреля 2020

Я знаю, почему это происходит, но хочу знать, каков правильный подход , чтобы избежать этого. useEffect вызывается дважды. один с data = null, а затем с «реальными» данными.

const [data, setData] = useState(null);
someServiceToFetchData.then(freshData => setData(freshData))

useEffect(() => {
    console.log("useEffect called");
}, [data]);

я должен делать что-то подобное везде?

useEffect(() => {
    if (data) {
        console.log("useEffect called with real data");
    }
}, [data]);

1 Ответ

3 голосов
/ 07 апреля 2020

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

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

Компонент

import React,  { useState, useEffect } from 'react';
import useEffectSkipInitialRender from "./hook";

const Test = (props) => {
    const [data, setData] = useState(null);

    new Promise((res, rej) => res('my data')).then(freshData => setData(freshData));

    useEffectSkipInitialRender(() => {
        console.log("useEffect called");
    }, [data]);

    return <div>hi</div>
};

export default Test;

Пользовательский хук

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

const useEffectSkipInitialRender = (callback, dataArr) => {
    const [data, setData] = useState(null);
    const isInitialRender = useRef(true);// in react, when refs are changed component dont re-render 

    useEffect(() => {
        if(isInitialRender.current){// skip initial execution of useEffect
            isInitialRender.current = false;// set it to false so subsequent changes of dependency arr will make useEffect to execute
            return;
        }
        return callback();
    }, dataArr);

};

export default useEffectSkipInitialRender;

Если вы хотите, чтобы эффект logi c был запускать только когда данные не равны NULL и данные изменяются, вы можете написать свой пользовательский хук следующим образом:

import React,  { useEffect } from 'react';

const useEffectOnDataChange = (callback, dataArr) => {
    const someIsNull = dataArr.some(data => data == null);

    useEffect(() => {
        if (someIsNull) return;
        return callback();
    }, dataArr);

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