han*_*ome 7 javascript reactjs react-hooks
我知道为什么会发生这种情况,但想知道避免这种情况的正确方法是什么。\nuseEffect 被调用两次。一个是 data = null,然后是“真实”数据。
\n\nconst [data, setData] = useState(null);\nsomeServiceToFetchData.then(freshData => setData(freshData))\n\nuseEffect(() => {\n console.log("useEffect called");\n}, [data]);\nRun Code Online (Sandbox Code Playgroud)\n\n我应该到处做这样的事情吗?
\n\nuseEffect(() => {\n if (data) {\n console.log("useEffect called with real data");\n }\n}, [data]);\nRun Code Online (Sandbox Code Playgroud)\n
如果你想跳过第一次渲染,你可以使用这样的状态标志。我发现下面的方法不太复杂。
import React, { useState } from 'react';
const Comp = ({dep}) => {
const [rendered, setRendered] = useState(false);
useEffect(() => {
if(rendered){
// do stuff
}
if( ! rendered ) {
setRendered(true);
}
}, [dep]);
// rest of the component code
return <></>
}
Run Code Online (Sandbox Code Playgroud)
众所周知,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;
Run Code Online (Sandbox Code Playgroud)
定制挂钩
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;
Run Code Online (Sandbox Code Playgroud)
如果您希望效果逻辑仅在数据不为空且数据更改时运行,您可以像这样编写自定义挂钩:
import React, { useEffect } from 'react';
const useEffectOnDataChange = (callback, dataArr) => {
const someIsNull = dataArr.some(data => data == null);
useEffect(() => {
if (someIsNull) return;
return callback();
}, dataArr);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
16679 次 |
| 最近记录: |