[英]Execute useEffect() only on specific setState()
I am using a hook component and several state variables.我正在使用一个钩子组件和几个 state 变量。 I have read about using
useEffect()
with params to get a kind of callback after updating a state.我已经阅读了有关在更新 state 后使用带有参数的
useEffect()
来获得一种回调的信息。 Example:例子:
export const hookComponent = () => {
const [var, setVar] = useState(null);
useEffect(() => {
//do things
}, [var])
}
In this example, useEffect()
would be executed on every setVar()
call.在此示例中,将在每个
setVar()
useEffect()
上执行 useEffect()。 In my case, I do not want to execute useEffect()
everytime, but only on specific occasions.就我而言,我不想每次都执行
useEffect()
,而只是在特定情况下执行。 I would like to give the setVar()
some kind of information which I can use in useEffect()
like setVar(newValue, true)
.我想给
setVar()
一些我可以在useEffect()
中使用的信息,比如setVar(newValue, true)
。
Note: I do not want to store this information in var.注意:我不想将此信息存储在 var 中。
Is there a way to do this?有没有办法做到这一点?
Like Nizar said, simple conditional check on 'var' in useEffect就像 Nizar 所说,在 useEffect 中对 'var' 进行简单的条件检查
If expensive calc you can如果计算昂贵,你可以
const expensiveValue = useMemo(() => {
// other logic here if needed
// could even be simple return var=='x'?true:false, although this would be easier to do in the useEffect hook?
return computeExpensiveValue(var);
},[var]);
useEffect(() => {
//do things
//expensiveValue only changes when you want it to from the memo
}, [expensiveValue])
Thank you sambomartin and Nizar for your input.感谢 sambomartin 和 Nizar 的意见。
For everyone looking for an answer: After some further research I found 3 possible solutions:对于所有寻找答案的人:经过进一步研究,我发现了 3 种可能的解决方案:
setState()
a callback as a second param.setState()
提供回调作为第二个参数。useRef
hook to determine where your state update is comming from.useRef
挂钩来确定 state 更新的来源。 You can use this information in the useEffect()
method.useEffect()
方法中使用此信息。 As far as I know, the useEffect only triggers if the dependency value changes , not simply by executing setValue.据我所知, useEffect 仅在依赖值更改时触发,而不仅仅是通过执行 setValue。
I offer you three solutions, the first one, close to what you want but without using useEffect hook, the second one is an extension of the first one, that may be required if you need control over the previous state, and the third, more general, like comments say, though it won't be triggered if the state is the same, even if you execute setValue .我为您提供三个解决方案,第一个接近您想要的但不使用 useEffect 挂钩,第二个是第一个的扩展,如果您需要控制以前的 state,则可能需要,第三个,更多一般,就像评论说的那样,尽管如果 state 相同,即使您执行 setValue 也不会触发它。
export default function MyComponent() {
const [state, setState] = useState(null);
const handleChangeSetState = (nextState, flag) => {
if (flag) {
specialUseCaseCb();
}
setState(nextState);
};
return <div>{/* ... */}</div>;
}
export default function MyComponent2() {
const [state, setState] = useState(0);
const handleChangeSetState = (increment, flag) =>
setState((prevState) => {
const nextState = prevState + increment;
// you may need prevState or nextState for checking your use case
if (flag) {
specialUseCaseCb();
}
return nextState;
});
return <div>{/* ... */}</div>;
}
export default function MyComponent3() {
const [state, setState] = useState("");
// notice that this will only be triggered if state changes
useEffect(() => {
if (state !== "my-special-use-case") return;
specialUseCaseCb();
}, [state]);
return <div>{/* ... */}</div>;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.