从后端获取数据导致无限循环并且永远不会成功加载

Fetching data from backend causes infinite loop and never successfully loads

这可能是我对此处显示的异步函数缺乏经验,但我遇到了一个问题,我的代码从后端获取模板以进行反应只是简单地重复,而没有正确地将状态设置为数据

import React, { useState} from 'react';
import './main.css';
import Frame from './Components/Frame';


function App() {
    const [view, setView] = useState(window.location.pathname);

    console.log('logging view ' + view);

    return (
        <div className="App container m-4">
            <Frame viewF={'nav'} />
            <div id='content'>
                <Frame viewF={view} />
            </div>
        </div>
    );

}

export default App;

主要成分

import React, { useState } from 'react';

function createMarkup(markup) {
    return { __html: markup };
}

const Frame = (props) => {
    const [content, setContent] = useState('');

    const contactBackend = async () => {
        try {
            const response = await fetch('http://localhost:5000/' + props.viewF, {
                'methods': 'GET',
                headers: {
                    'Content-Type': 'application/json'
                }
            })
            if (!response.ok) {
                throw Error(response.statusText);
            }
            //const data = response.json(); //alternate approach
            //console.log(data);
            setContent(response.json());

        } catch (error) {
            console.log(error);
        }
    }

    contactBackend();

    return (
        <div className="m-2" dangerouslySetInnerHTML={createMarkup(content)}>

        </div>
    )

};

export default Frame;

后端可以发送数据,它在更早更简单的版本中工作。我还可以通过一些控制台日志看到返回值。但它最多放入返回的 div 是 [object Promise] 然后它发送 1000 次请求直到后端崩溃

代码在函数体中无条件调用contactBackend,结果是入队状态更新,触发组件重新渲染。这是无意的side-effect.

通常这会在安装时在 useEffect 挂钩中调用。

response.json() 也是 returns 一个 Promise,因此您还想等待它解决。

示例:

useEffect(() => {
  const contactBackend = async () => {
    try {
      const response = await fetch('http://localhost:5000/' + props.viewF, 
        {
          'methods': 'GET',
          headers: {
          'Content-Type': 'application/json'
          }
        }
      );

      if (!response.ok) {
        throw Error(response.statusText);
      }

      const content = await response.json();
      setContent(content);
    } catch (error) {
      console.log(error);
    }
  }

  contactBackend();
}, []); // <-- empty dependency to run once after initial render