我建议在这里看看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 // 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 return ( <div> <div>Counter is {counter}</div> <button onClick={fn}>add +1 count</button> </div> );}


