我正在尝试useEffect示例,如下所示:
useEffect(async () => { try { const response = await fetch(`https://www.reddit.com/r/${subreddit}.json`); const json = await response.json(); setPosts(json.data.children.map(it => it.data)); } catch (e) { console.error(e); } }, []);
我在控制台中收到此警告。但是对于我认为的异步调用,清理是可选的。我不确定为什么会收到此警告。链接沙箱示例。https://codesandbox.io/s/24rj871r0p
我建议在这里看看Dan Abramov(React核心维护者之一)的答案:
我认为您正在使它变得比所需的更加复杂。
function Example() { const [data, dataSet] = useState<any>(null) useEffect(() => { async function fetchMyAPI() { let response = await fetch('api/data') response = await response.json() dataSet(response) } fetchMyAPI() }, []) return <div>{JSON.stringify(data)}</div> }
从长远来看,我们会阻止这种模式,因为它会鼓励比赛条件。例如- 在通话开始和结束之间可能会发生任何事情,并且您可能会获得新的道具。相反,我们建议使用Suspense进行数据提取,看起来更像
const response = MyAPIResource.read();
并没有影响。但是与此同时,您可以将异步内容移到一个单独的函数中并进行调用。
您可以在此处阅读更多有关实验性悬念的信息。
如果要在eslint之外使用函数。
function OutsideUsageExample() { const [data, dataSet] = useState<any>(null) const fetchMyAPI = useCallback(async () => { let response = await fetch('api/data') response = await response.json() dataSet(response) }, []) useEffect(() => { fetchMyAPI() }, [fetchMyAPI]) return ( <div> <div>data: {JSON.stringify(data)}</div> <div> <button onClick={fetchMyAPI}>manual fetch</button> </div> </div> ) }
与useCallback useCallback一起使用。沙盒。
import React, { useState, useEffect, useCallback } from "react"; export default function App() { const [counter, setCounter] = useState(1); // if counter is changed, than fn will be updated with new counter value const fn = useCallback(() => { setCounter(counter + 1); }, [counter]); // if counter is changed, than fn will not be updated and counter will be always 1 inside fn /*const fnBad = useCallback(() => { setCounter(counter + 1); }, []);*/ // if fn or counter is changed, than useEffect will rerun useEffect(() => { if (!(counter % 2)) return; // this will stop the loop if counter is not even fn(); }, [fn, counter]); // this will be infinite loop because fn is always changing with new counter value /*useEffect(() => { fn(); }, [fn]);*/ return ( <div> <div>Counter is {counter}</div> <button onClick={fn}>add +1 count</button> </div> ); }