【问题标题】:How to prevent React Hook's useEffect from fetching data multiple times如何防止 React Hook 的 useEffect 多次获取数据
【发布时间】:2020-01-07 20:10:12
【问题描述】:

下面的示例显示了我对useEffect() 的使用如何导致多个Ajax 请求。在组件的初始渲染中,此请求会发出两次。如果标签被更改,则此请求会发出两次。

我可以使用某种内部状态变量来跟踪我是否已经获取。或者我可以创建一种堆栈,在其中推送某种类型的潜在请求,然后在返回之前弹出堆栈并运行最终请求。但所有这些似乎都是一个黑客。

(如果有帮助,应用程序会更大一些,而且我正在使用 redux。更广泛的解决方案是否类似于 redux-saga 的取消?)

const Thing => () => {
  const [tagId, setTagId] = useState(null)
  const [query, setQuery] = useState('')

  useEffect(() => {
    doSomeAjaxAndUpdateResults()
    setQuery('')
  }, [tagId])

  useEffect(() => {
    doSomeAjaxAndUpdateResults()
  }, [query])

  // ... bunch of extra effects with similar dependencies.
}

【问题讨论】:

    标签: reactjs react-hooks


    【解决方案1】:

    您可以将两个内部状态变量合并到一个 useEffect 挂钩中,然后如果有一个更改,您可以执行 doSomeAjaxAndUpdateResults

    const Thing = (prop) => {
      const [tagId, setTagId] = useState(null)
      const [query, setQuery] = useState('')
    
      useEffect(() => {
        doSomeAjaxAndUpdateResults()
        setQuery('')
      }, [tagId, query])
    
      return ...;
    }
    

    以下是同样依赖于 props 被传递的实时示例:https://stackblitz.com/edit/react-wzmxmj

    第一次渲染带有初始值,第二次渲染带有传递的道具,然后后续的道具更改将触发一次调用。

    【讨论】:

    • 这适用于我提供的示例,但您通过将逻辑折叠到一个 useEffect 方法来实现。我有很多 useEffect() -- 我想我应该提供一个更大的代码示例!
    • 我的答案是在您提供的示例的上下文中,根据您的需要对其进行更新,如果出现警告,将使用不同的解决方案再次尝试
    【解决方案2】:

    您在 2 个 useEffects 中调用了相同的函数,您可以先检查您正在观看的 useEffects 是 '' 还是 null [tagId][query],您可以试试这个下面的代码。希望对你有帮助

    const Thing => () => {
      const [tagId, setTagId] = useState(null)
      const [query, setQuery] = useState('')
    
      useEffect(() => {
        if(tagId && tagId !== null) {
           doSomeAjaxAndUpdateResults()
           setQuery('')
        }
      }, [tagId])
    
      useEffect(() => {
        if(query && query !== '') {
          doSomeAjaxAndUpdateResults()
        }
      }, [query])
    }
    

    【讨论】:

    • Javascript 认为空字符串是错误的,所以 query !== '' 只有在 query 也为假时才会为假。此外,在检查 null undefined 的情况下,==!= 将匹配 null 和 undefined,这通常是您想要的(但通常 ===!== 在其他情况下是首选例)。
    • 但是在 useEffect 中,它最初会运行 useEffect [query][tagId],即使它是 ''null 所以你必须先检查它,然后再执行[query][tagId] 值已更改,这就是它不断重新渲染的原因。
    • 我认为你的逻辑是倒退的......也许你想要if (!tagId && tagId !==null)…if(!query && query !== '')… 代替?这使得它只在值是假的但恰好null时运行tagID相关逻辑,并且仅在query为假但不完全@时运行query相关日志987654346@
    • 不,if(tagId) 表示你正在检查它是否有价值,lmao
    • Michael,它工作得很好,而且这是一个相当不错的习惯。一个缺点是它让我怀疑你是否真的打算做其他事情,所以在这方面还不清楚,因为我想多了。 Javascript 的真实性让我吃了很多次......
    猜你喜欢
    • 2021-03-23
    • 2019-07-27
    • 1970-01-01
    • 2020-06-23
    • 1970-01-01
    • 2019-10-08
    • 2019-11-11
    • 2022-07-12
    • 2019-11-24
    相关资源
    最近更新 更多