我知道为什么会发生这种情况,但想知道避免这种情况的正确方法是什么。
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]);
最佳答案
众所周知,useEffect 在初始渲染时调用一次,并且在随后更改依赖数组的值时调用一次。
在您的情况下,要跳过 useEffect 的初始执行(空情况),请编写一个小的自定义 Hook ,例如可以在需要时通用使用。
零件
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;
定制 Hook
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;
如果您希望效果逻辑仅在数据不为空且数据更改时运行,您可以编写自定义 Hook ,如下所示:
import React, { useEffect } from 'react';
const useEffectOnDataChange = (callback, dataArr) => {
const someIsNull = dataArr.some(data => data == null);
useEffect(() => {
if (someIsNull) return;
return callback();
}, dataArr);
}
关于javascript - useEffect 调用了两次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61069240/