UseEffect 中的异步生成器 - 如何取消订阅更新

Asynchronous Generators in UseEffect - how to unsubscribe from updates

我一直在尝试在 Typescript React 应用程序中使用异步生成器。

我创建了以下组件:

import React, {useEffect, useState} from 'react'

const delay = (ms : number) => new Promise(resolve => setTimeout(resolve, ms))

const fetchData = async (count : number, url: string) => { 
    await delay(1000);
    const title : string = await fetch(`${url}/${count}`).then(response => response.json()).then(data => data.title)
    return title; 
}

const asyncGenerator = async function* () { 
    let count : number = 1;
    const url : string = 'http://jsonplaceholder.typicode.com/posts';
    while(true) { 
        yield fetchData(count, url)
        count++;
    }

}

const UseEffectComponent = () => { 
    const [titles, setTitles] = useState<string[]>([])

 
    useEffect(() => { 
        (async () => { 
            for await (const title of asyncGenerator()) { 
                setTitles(t => [...t, title])
            }
        })();
        
        
    }, [])

    return (
        <div>
            <div>
                {titles.map(t => <p>{t}</p>)}
            </div>
        </div>
    )
}

export default UseEffectComponent;

本质上,我创建了一个 post 标题流,由 asyncGenerator 函数提供,它将通过调用 API 每秒从占位符 API 获取数据=13=] 使用 delay 引入人为的 1000ms 延迟。

我很好奇从组件本身的流中读取此数据的最佳方法是什么。我当前的实现使用 useEffect:

useEffect(() => { 
    (async () => { 
        for await (const title of asyncGenerator()) { 
            setTitles(t => [...t, title])
        }
    })();

没有清理代码 - 这意味着即使卸载了组件,该流也将继续提供数据。我不确定解决此问题的最佳方法是什么。当组件卸载时,我可以退出这个 for of 循环吗?或者是否有更好的方法来使用我的流中的数据?

您可以添加 isMounted 来检查组件是否已卸载。

useEffect(() => { 
  let isMounted = true;
  (async () => {
      for await (const title of asyncGenerator()) { 
        if(!isMounted){
          break;
        }
        setTitles(t => [...t, title])
      }
  })();  

  return () => {
    isMounted = false;
  };
}, [])