【问题标题】:How do I fire React useEffect hook only once after state change?如何在状态更改后仅触发一次 React useEffect 挂钩?
【发布时间】:2021-07-18 21:10:51
【问题描述】:

我是 React 钩子的新手,我不确定如何实现以下目标。假设我有state1state2,我使用useEffect 挂钩调用asyncFn1 并更新state1

现在我想等待state1 更改并使用state1 值调用asyncFn2 并更新state1state2。这个asnycFn1asyncFn2 只能调用一次。

如果我只是使用另一个useEffect 来调用asyncFn2,我不会得到state1 的值。我该如何解决?

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();
}, [])

【问题讨论】:

  • 为什么要从asyncFn2 更新state1_state1asyncFn2 的输入是否与您要调用 setState1 的状态不同?
  • 参见stackoverflow.com/questions/59492626/…,同样的逻辑,有一个充当“调用一次”标志的 ref。
  • @PatrickRoberts 是的,状态 1 将导致不同的 asyncFn2 结果,该结果将用于再次更新 state1。
  • @DennisVash 谢谢! useRef 正是我所需要的。

标签: javascript reactjs react-hooks use-effect


【解决方案1】:

你需要的是一个 useEffect,它在 useEffect 依赖数组中有你的 state1,所以当你的 state1 值改变时触发它,如下所示:

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

如果您希望 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
}

【讨论】:

  • 我看到你修复了你的例子,但我的陈述没有错,之前你在useEffect 中调用了useCallback,试试这个代码并告诉我你的发现
  • 另外,它应该是!dataLoadedRef.current 而不是!dataLoadedRef,这始终是一个真实的陈述
  • 是的,感谢您的指点,这是一个很好的观点 - 但是您所说的不使用函数内部的钩子,那么函数组件是什么?
  • 在 React 术语中,有“函数组件”,当说“函数”时,它们只是 JS 函数,请参阅reactjs.org/docs/hooks-rules.html“不要从常规 JavaScript 函数调用 Hooks”
猜你喜欢
  • 2019-09-23
  • 2020-11-06
  • 2020-08-03
  • 2021-03-13
  • 2020-02-12
  • 2019-12-27
  • 2019-07-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多