为什么这个异步函数会无限循环?

问题描述 投票:0回答:5

我已经将我的应用程序降至最低限度,试图理解为什么它是无限循环......但我不明白。

const App = () => {

  console.log("just logging that the app ran!")
  
  const [data, setData] = useState('initial state');
  
  const getAsset = async () => {
  
    console.log("logging that getAsset ran!")

  setData("new state!")
  console.log(data)
}
  
  getAsset();
  
  return (

    <div >
      {data}
    </div>
  );
}

export default App;

有什么指点吗?

错误信息:

react-dom.development.js:14997 Uncaught Error: Too many re-renders. React limits the number of renders to prevent an infinite loop.
javascript reactjs asynchronous async-await
5个回答
2
投票

只需调用

getAsset
钩子内的
useEffect
即可。但不知道为什么要创建这个功能
async
。在您的情况下,
setData
会导致重新渲染并再次调用
getAsset
函数,从而导致循环

工作沙箱:https://codesandbox.io/s/react-hooks-example-forked-0rqb9?file=/src/App.js

const App = () => {

  const [data, setData] = useState("initial state");

  useEffect(() => {
    getAsset();
  }, []);

  const getAsset = async () => {
    setData("new state!");
  };

  return <div>{data}</div>;
};

export default App;

1
投票

每次组件渲染时,您的代码都会调用 getAsset() 和 getAsset setState (setData),当您更改状态时,组件重新渲染,它再次调用 getAsset 并再次重新渲染.........................

你需要在挂载时调用它,所以使用 useEffect


const App = () => {

  console.log("just logging that the app ran!")
  
  const [data, setData] = useState('initial state');
  
  const getAsset = async () => {
  
    console.log("logging that getAsset ran!")

  setData("new state!")
  console.log(data)
}
 
 useEffect(() => {
getAsset();

},[])

  
  return (

    <div >
      {data}
    </div>
  );
}

export default App;

1
投票

问题在于,每次状态发生变化时,React 都会重新运行 App,这意味着在 App 中直接调用 getAsset,而不进行任何检查以查看它是否已运行,这将导致循环。

// Runs when the component is rendered.
const App = () => {
  // ...
  getAsset(); // Sets state, re-rendering app.
  // ...
  return (
    <div >
      {data}
    </div>
  );
}

要修复此问题,请检查以确保状态仅设置一次或新状态不同时设置,这样就不会发生循环行为。


0
投票

您的组件将在执行的每个操作上重新渲染,一次又一次地重新运行异步函数。避免这种情况的一种方法是使用 useEffect 挂钩和您选择的依赖项。这样,异步函数只会在满足特定条件时运行。


0
投票
you can use some thing like this 

 fetchSummary(Props).then((d)=>{
    setSummary(d);
    setStatus('success');
    setModel(d.model);
    console.log("response after call" + JSON.stringify(d));
  })

 useEffect(() => {
    fetchData();
  },[]); 

//-> triggers one time if we specify empty array

-> fetchSummary is promise function 
-> on promise function you can call then
-> then block will call only once promise is resolved
© www.soinside.com 2019 - 2024. All rights reserved.