簡體   English   中英

React useEffect清理功能取決於異步等待結果

[英]React useEffect cleanup function depends on async await result

我有一個react組件,該組件異步獲取一些資源,然后訂閱資源更改。

問題在於清除功能不在此資源的關閉中:

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

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

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

由於不允許在useEffect使用異步函數, useEffectuseEffect的cleanup函數中退訂該資源的最佳方法是什么?

我看到這里有兩個“副作用”。

  1. 獲取資源(需要發生一次,dependency []
  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負責取消/訂閱回調。

並檢查每個useEffectdeps列表(前者為空[]而后者取決於[resource]

這是一個解決方案,可能是丑陋的...但是仍然是解決方案:)

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM