Reactjs 避免在更新上下文时运行效果挂钩
我有一个组件Reactjs 避免在更新上下文时运行效果挂钩,reactjs,react-hooks,Reactjs,React Hooks,我有一个组件MyContainer,它有一个状态变量(通过useStatehook定义),定义了一个上下文提供程序,它将状态变量作为值传递给该提供程序,还包含两个子组件MySetCtxComponent和MyViewCtxComponent MySetCtxComponent可以更改存储在调用set函数的上下文中的值,该函数也作为上下文的一部分传递,但不会呈现它 相反,MyViewCtxComponent会呈现存储在上下文中的值 MySetCtxComponent还通过useffecthook定
MyContainer
,它有一个状态变量(通过useState
hook定义),定义了一个上下文提供程序,它将状态变量作为值传递给该提供程序,还包含两个子组件MySetCtxComponent
和MyViewCtxComponent
MySetCtxComponent
可以更改存储在调用set函数的上下文中的值,该函数也作为上下文的一部分传递,但不会呈现它
相反,MyViewCtxComponent会呈现存储在上下文中的值
MySetCtxComponent
还通过useffect
hook定义了一个效果。例如,此效果用于以固定的时间间隔更新上下文的值
这三个组件的代码是
MyContainer
export function MyContainer() {
const [myContextValue, setMyContextValue] = useState<string>(null);
const setCtxVal = (newVal: string) => {
setMyContextValue(newVal);
};
return (
<MyContext.Provider
value={{ value: myContextValue, setMyContextValue: setCtxVal }}
>
<MySetCtxComponent />
<MyViewCtxComponent />
</MyContext.Provider>
);
}
导出函数MyContainer(){
const[myContextValue,setMyContextValue]=useState(null);
常量setCtxVal=(newVal:string)=>{
setMyContextValue(newVal);
};
返回(
);
}
MySetCtxComponent
(加上一个全局变量,使示例更简单)
let计数器=0;
导出函数MySetCtxComponent(){
const myCtx=useContext(MyContext);
useffect(()=>{
console.log(“=======>>>>>>>>>>>>在MySetCtxComponent中运行的使用效果”);
const intervalID=setInterval(()=>{
myCtx.setMyContextValue(“新值”+计数器);
计数器++;
}, 3000);
return()=>clearInterval(intervalID);
},[myCtx]);
返回(计数器=0)}>重置;
}
MyViewCtxComponent
export function MyViewCtxComponent() {
const myCtx = useContext(MyContext);
return (
<div>
This is the value of the contex: {myCtx.value}
</div>
);
}
导出函数MyViewCtxComponent(){
const myCtx=useContext(MyContext);
返回(
这是contex的值:{myCtx.value}
);
}
现在我的问题是,每次更新上下文时,MySetCtxComponent
的效果都会再次运行,即使这根本不是必需的,因为更新上下文时不需要渲染MySetCtxComponent
。但是,如果我从useffect
钩子的依赖项数组中删除myCtx
(这会在上下文更新时阻止效果钩子),那么我会得到一个es lint警告,例如React钩子useffect缺少依赖项:“myCtx”。包括它或删除依赖项数组react hooks/deps
最后一个问题是:在这种情况下,忽略警告是安全的,还是我有一个基本的设计错误,可能应该选择使用商店?认为这个例子看起来很愚蠢,但是它是真实场景中最简化的版本。
要复制案例解决此问题的一种模式是将上下文一分为二,为操作提供一个上下文,为访问上下文值提供另一个上下文。这允许您正确地实现useEffect的预期依赖关系数组,同时也不会在只有上下文值更改时不必要地运行它
const{useState,createContext,useContext,useffect,useRef}=React;
const ViewContext=createContext();
const ActionsContext=createContext();
函数MyContainer(){
const[contextState,setContextState]=useState();
返回(
)
}
函数MySetCtxComponent(){
const setContextState=useContext(ActionsContext);
常量计数器=useRef(0);
useffect(()=>{
console.log(“=======>>>>>>>>>>>>在MySetCtxComponent中运行的使用效果”);
const intervalID=setInterval(()=>{
setContextState(“新值”+计数器当前值);
计数器.current++;
}, 1000);
return()=>clearInterval(intervalID);
},[setContextState]);
返回(counter.current=0)}>Reset;
}
函数MyViewCtxComponent(){
const contextState=useContext(ViewContext);
返回(
这是上下文的值:{contextState}
);
}
ReactDOM.render(
,
document.getElementById(“根”)
);代码>
您通常会使用
export function MyViewCtxComponent() {
const myCtx = useContext(MyContext);
return (
<div>
This is the value of the contex: {myCtx.value}
</div>
);
}