【问题标题】:React useEffect cleanup function depends on async await resultReact useEffect 清理功能依赖于异步等待结果
【发布时间】:2019-07-20 00:28:07
【问题描述】:

我有一个 react 组件,它异步获取一些资源,然后订阅资源更改。

问题是清理函数不在这个资源的闭包中:

useEffect(() => {
  const onResourceChange = () => { 
    console.log('resource changed');
  };

  getSomeResource().then(resource => {
    resource.subscribe(onResourceChange);
  });

  return () => {
    resource.unsubscribe(onResourceChange); // Error! resource is undefined
  }
}, []);

由于不允许在useEffect 中使用异步函数,在useEffect 的清理函数中取消订阅此资源的最佳方法是什么?

【问题讨论】:

    标签: javascript reactjs async-await react-hooks


    【解决方案1】:

    我看到这里有两个“副作用”。

    1. 获取资源(需要发生一次,依赖[]
    2. 订阅/取消订阅回调(需要在资源更改、依赖、[resource] 时发生)

    所以我

    1. 将它们分成两个“效果”(步骤,每个处理一个副作用)
    2. 并将其提取到自定义挂钩中
        function useResource() {
            const [resource, setResource] = useState(undefined)
    
            const onResourceChange = () => console.log('resource changed');
    
            // Get the resource, initially.
            useEffect(() => {
              getSomeResource(setResource)
            }, [])
    
            // When the resource is retrieved (or changed),
            // the resource will subscribe and unsubscribe
            useEffect(() => {
              resource.subscribe(onResourceChange)
              return () => resource.unsubscribe(onResourceChange)
            }, [resource])
        }
    
        // Use it like this
        function App() {
            useResource()
    
            return <>your elements</>
        }
    

    如您所见,第一个useEffect 只负责获取“资源”,而第二个useEffect 负责取消/订阅回调。

    并查看每个useEffect 中的deps 列表(前者为空[],而后者取决于[resource]

    【讨论】:

      【解决方案2】:

      这是一个解决方案,可能是丑陋的......但仍然是一个解决方案:)

      useEffect(() => {
          const onResourceChange = () => { 
              console.log('resource changed');
          };
      
          let data = {};
      
          getSomeResource().then(resource => {
              data.resource = resource;
              resource.subscribe(onResourceChange);
          });
      
          return () => {
              data.resource && data.resource.unsubscribe(onResourceChange); // Error! resource is undefined
          };
      }, []);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2020-04-08
        • 1970-01-01
        • 1970-01-01
        • 2021-02-07
        • 1970-01-01
        • 1970-01-01
        • 2023-04-08
        • 1970-01-01
        相关资源
        最近更新 更多