`useEffect` 的预期回报用于什么?

Pri*_*ran 22 ecmascript-6 reactjs react-hooks

在钩子的 React文档中,他们说:

“这还允许您使用效果内部的局部变量处理无序响应”

useEffect(() => {
    let ignore = false;
    async function fetchProduct() {
      const response = await fetch('http://myapi/product/' + productId);
      const json = await response.json();
      if (!ignore) setProduct(json);
    }

    fetchProduct();
    return () => { ignore = true };
  }, [productId]);
Run Code Online (Sandbox Code Playgroud)

演示应用

请通过解释帮助我更好地理解这一点:

  1. 为什么 return 是一个函数? return () => { ignore = true };
  2. 这个例子中被忽略的用途是什么?

谢谢!

小智 67

我会在这里解释一下,因为我花了一段时间才理解上面的解释,所以我会尽量让其他人更简单。

问题解答:
1. 为什么 return 是一个函数?return () => { ignore = true };
useEffect提供了return函数的使用,用于清理功能的目的,OK!,什么时候需要清理?例如,如果您订阅了某些内容,并且想要取消订阅,则应该在 useEffect 内的“返回函数”中添加取消订阅逻辑,而不是将逻辑放在其他地方,这可能会导致竞争条件!

2. 本例中忽略的用途是什么?
用作ignore告诉函数是否忽略 api 调用的标志。什么时候用的?当你有竞争条件时。

[竞争条件示例-您可以忽略这部分,您已经熟悉了竞争条件]例如,您单击产品列表,当单击每个产品时,如果您快速单击,您将使用该产品信息更新页面在产品中多次,每当product_id发生更改时,useEffect都会更新,并且在某些时候单击product1 [将调用product1的api],然后快速单击product2 [将调用product2的api并检索数据导致-> setProduct(product2data) ]而 Product1 的数据刚刚到达,导致 -> setProduct(product1data)。这样我们就点击了product2!但product1数据出现在页面上!

巴特特这有什么关系ignore
【逻辑解释】
ignore亲爱的,告诉setProduct忽略旧数据,不设置它,这样我们只会设置最后点击的产品,即使旧数据稍后到达。
[代码解释]
1-第一个场景:没有比赛,点击product1 ->ignore为 false ,调用 api ,检索数据,if(!ignore) -> 将设置product1数据,现在清理函数将设置ignore为 true ,恭喜!。

2-第二个场景->竞争条件,点击product1->忽略为假,调用api,[数据仍未到达],现在点击产品2忽略为假,调用api,数据到达,if()->!ignore将设置product2数据,清理函数会将ignore设置为true,product1函数数据已到达->if( !ignore)->为falseOOOPS 不会将product1数据设置为“旧数据”。

这样我们将始终拥有新数据。欢呼吧:D

  • 我喜欢你作为一个刚刚经历过“啊哈”时刻的人激动地回答这个问题的方式 (5认同)
  • 你能解释一下为什么product2数据会先设置吗?我看到 useffect 中有 async wait 。即使我点击product2,它仍然需要等待product1完成。正确的?我是否误解了什么?抱歉,我刚学反应。 (2认同)
  • @FrogTuna 产品2 数据可能会首先设置,也可能不会 - 这是一场竞赛。假设来自product1调用的数据非常大,而来自product2调用的数据非常小,则product2调用有可能先返回,即使它的调用稍晚于product1调用。正如您所注意到的,它们是异步调用,这意味着它们通过互联网发送,而无需等待彼此先返回。 (2认同)

rav*_*l91 25

为什么 return 是一个函数?返回 () => { 忽略 = 真 };

文档中

为什么我们从我们的效果中返回一个函数?这是效果的可选清理机制。每个效果都可能返回一个在它之后进行清理的函数。这让我们保持添加和删除订阅的逻辑彼此接近。它们是相同效果的一部分!

React 什么时候清理效果?当组件卸载时,React 执行清理。但是,正如我们之前所了解的,效果在每次渲染时都会运行,而不仅仅是一次。这就是为什么 React 还会在下次运行效果之前清除上一次渲染中的效果。我们将讨论为什么这有助于避免错误以及如何选择退出这种行为,以防它在后面产生性能问题。

这个例子中被忽略的用途是什么?

最初在useEffectHookignore中设置为,let ignore = false;。当fetchProduct函数执行时,它会检查ignoreistrue并相应地设置setProduct(json)。这意味着我们已经在using 中state调用product并设置了值。此状态用于在页面上呈现详细信息。 statesetProduct(json)product

注意:作为[productId]第二个参数传递给useEffectfetchProduct函数只会在productId更改时执行。

请参阅通过跳过效果优化性能


小智 12

// all imports
function myFunc() {
  useEffect(() => {
    // it prints when mouse moves
    const a = addEventListener('mouse', console.log('mouse moves')); 

    return () => {
      // whenever the component removes it will executes
      removeEventListener(a);
    };
  }, []);
}
Run Code Online (Sandbox Code Playgroud)


小智 6

返回函数是清理函数,或者当用户离开页面时,组件将被卸载。数组是最后一部分,您可以在其中放置将在整个组件生命周期中更新的状态。
了解更多