简体   繁体   English

如何在 state 更改后仅触发一次 React useEffect 挂钩?

[英]How do I fire React useEffect hook only once after state change?

I am new to React hooks and I am not sure how to achieve following goal.我是 React 钩子的新手,我不确定如何实现以下目标。 Let's say I have state1 and state2 , and I use useEffect hook to call asyncFn1 and update state1 .假设我有state1state2 ,我使用useEffect挂钩来调用asyncFn1和更新state1

Now I want to wait for state1 change and use state1 value to call asyncFn2 and update both state1 and state2 .现在我想等待state1更改并使用state1值调用asyncFn2并更新state1state2 This asnycFn1 and asyncFn2 should only be called once.这个asnycFn1asyncFn2应该只被调用一次。

If I just use another useEffect to call asyncFn2 , I won't get the state1 value.如果我只是使用另一个useEffect来调用asyncFn2 ,我将不会获得state1值。 How do I solve that?我该如何解决?

const [state1, setState1] = useState(null);
const [state2, setState2] = useState(null);

const asyncFn1 = async() => {
  // async call to get state 1 data
  // setState1
}

const asyncFn2 = async(_state1) => {
  // use state1 data to make async call to get state 2 data
  // state2 data will be used to update both state1 and state2
}

useEffect(() => {
  asyncFn1();
}, [])

What you need here is a useEffect which has your state1 in the useEffect dependency array, so to trigger it any time your state1 value changes, as such:你需要的是一个 useEffect,它在 useEffect 依赖数组中有你的state1 ,所以只要你的state1值发生变化就触发它,如下所示:

useEffect(() => {
   state1 && asyncFn2()
}, [state1])

In case you want your asyncFn2 to trigger only once after you get the data for state1, you can just add a ref to check when that's being called:如果您希望asyncFn2在获取 state1 的数据后仅触发一次,则只需添加一个 ref 以检查何时调用它:

const dataLoaded = useRef(false)

useEffect(() => {
   if(state1 && !dataLoaded.current) {
      asyncFn2()
   }
}, [state1])

const asyncFn2 = async () => {
   // Your logic here

   // Set dataLoaded on true once you have updated what you need successfully
   dataLoaded.current = true
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM