Reactjs 停止在挂载上运行useEffect
我只想在依赖项列表更改时运行useEffect,它也会在每次装入组件时运行,有没有办法不在装入时启动 如果出现某些值,可以告诉React to skip应用效果 在重新渲染之间没有更改 我最初认为这意味着它不应该在后续的挂载上重新渲染,但是 我在母版“页面”(react router)中显示一个记录列表,用户可以选择一个记录并转到详细信息页面,然后返回母版页-因此在该场景中,母版列表组件完全卸载/装载。每次我加载“母版页”时,我都会看到正在获取的数据,我只希望在其中一个依赖项更改时发生这种情况;这些依赖项和数据本身存储在Redux中,因此它们是全局的 是否可以使useEffect或另一个钩子仅在依赖项更改时触发Reactjs 停止在挂载上运行useEffect,reactjs,react-redux,react-hooks,use-effect,Reactjs,React Redux,React Hooks,Use Effect,我只想在依赖项列表更改时运行useEffect,它也会在每次装入组件时运行,有没有办法不在装入时启动 如果出现某些值,可以告诉React to skip应用效果 在重新渲染之间没有更改 我最初认为这意味着它不应该在后续的挂载上重新渲染,但是 我在母版“页面”(react router)中显示一个记录列表,用户可以选择一个记录并转到详细信息页面,然后返回母版页-因此在该场景中,母版列表组件完全卸载/装载。每次我加载“母版页”时,我都会看到正在获取的数据,我只希望在其中一个依赖项更改时发生这种情况;
const {page, pageSize, search, sorts} = useSelector(getFilters);
const data = useSelector(getData);
useEffect(() => {
console.log("fetching");
dispatch(fetchData(page, pageSize, search, sorts));
}, [page, pageSize, search, sorts]);
您无法对其进行开箱即用的配置 但是,常见的模式是使用一些
isMounted
标记,如下所示:
// Is Mounted
const useFetchNotOnMount = () => {
...
const isMounted = useRef(false);
useEffect(() => {
if (isMounted.current) {
console.log('fetching');
dispatch(fetchData(filters));
} else {
isMounted.current = true;
}
}, [dispatch, filters]);
};
// Same (Is First Render)
const useFetchNotOnMount = () => {
...
const isFirstRender = useRef(true);
useEffect(() => {
if (isFirstRender.current) {
isFirstRender = false;
} else {
console.log("fetching");
dispatch(fetchData(filters));
}
}, [dispatch, filters]);
};
如果您有多个
useffect
,以防止在开始时运行,则可以执行以下操作:
export default function App() {
const mountedRef = useMountedRef();
const [isLoggedIn, setLoggedIn] = React.useState(false);
const [anotherOne, setAnotherOne] = React.useState(false);
React.useEffect(() => {
if (mountedRef.current) {
console.log("triggered", isLoggedIn);
}
}, [isLoggedIn]);
React.useEffect(() => {
if (mountedRef.current) {
console.log("triggered", anotherOne);
}
}, [anotherOne]);
React.useEffect(() => {
if (mountedRef.current) {
console.log("triggered", isLoggedIn, anotherOne);
}
}, [anotherOne, isLoggedIn]);
return (
<div>
<button onClick={() => setLoggedIn(true)}>Login</button>
</div>
);
}
const useMountedRef = () => {
const mountedRef = React.useRef(false);
React.useEffect(() => {
setTimeout(() => {
mountedRef.current = true;
});
}, []);
return mountedRef;
};
导出默认函数App(){
const mountedRef=useMountedRef();
const[isLoggedIn,setLoggedIn]=React.useState(false);
const[anotherOne,setAnotherOne]=React.useState(false);
React.useffect(()=>{
if(mountedRef.current){
console.log(“已触发”,isLoggedIn);
}
},[isLoggedIn]);
React.useffect(()=>{
if(mountedRef.current){
console.log(“已触发”,另一个);
}
},[另一个];
React.useffect(()=>{
if(mountedRef.current){
console.log(“已触发”,isLoggedIn,另一个);
}
},[另一个,伊斯洛格丁];
返回(
setLoggedIn(true)}>Login
);
}
常量useMountedRef=()=>{
const mountedRef=React.useRef(false);
React.useffect(()=>{
设置超时(()=>{
mountedRef.current=true;
});
}, []);
返回安装的REF;
};
演示:
重要的一点是,您必须使用setTimeout
进行合理的延迟,以确保在所有初始使用效果之后,ref值都设置为true