我正在使用一个反应应用程序,其上下文包含一个单词列表。我有一个 context 的子组件,它使用上下文函数来编辑当前单词(设置单词列表)。 当我使用 useContext 执行此操作时,它会渲染子组件(全部!)。
export default function EditWordlistElem({content,elemId}){
const {editWordlist} = useWordlist(); // using context
const {newValue,setNewValue} = useState(content); // holds edited value
return (<div>
{/* Some code for getting edited value*/}
<button onClick={()=>editWordlist(newValue,elemId))>
Edit
</button>
</div>);
}
我的观点是,我实际上并不需要在子组件每次启动时都更新编辑功能,而仅在编辑时需要(例如按下按钮时)。
但是,使用 React hooks 尝试有条件地访问上下文或在回调内访问上下文是非法的。
来自 https://reactjs.org/docs/hooks-rules.html
仅调用顶层的钩子
不要在循环、条件或嵌套函数内调用 Hook。
我如何才能仅在单击按钮时获取上下文值,这样它就不会在每次上下文更改时渲染此组件?
如果您的钩子使用 useContext 订阅 WordList 值,则每次更新单词列表时它将重新渲染。从那里开始,订阅该钩子的任何组件也将重新渲染,从而导致整个子树重新渲染。
优化该功能的一种方法是使用两个上下文提供程序。一种用于存储状态中的实际值,另一种用于存储调度/设置器函数,包括 editWordlist。由于 editWordlist 引用不应更改,因此您可以调用此函数而无需订阅值。
有关此模式的更详细说明,请参阅:https://kentcdodds.com/blog/how-to-optimize-your-context-value。
最后,如果你使用的是 React 19,他们引入了 use 函数,可以在不遵循 hooks 规则的情况下加载上下文值。