为什么我在 ReactJS 中的状态变量不呈现,为什么它未定义?

Why does my state variable in ReactJS not render and why is it undefined?

React 和 JavaScript 初学者,如果这是一个简单的修复,请原谅我。

我正在从服务器获取数据并打算解析响应并将响应的元素存储在作为状态变量的数组中,因为我想使用状态的变化来相应地更新页面。

我遇到的问题是,在使用 fetch() 时,我能够从服务器检索数据,但显然我无法正确使用 setState() 将数据分配给变量。我读过 setState() 是异步的,因此您的状态变量可能不会立即更新,在这种情况下,我想知道我是否可以在我的状态变量(数组)更新时呈现应用程序。

下面是我的代码:

import React, { Component } from 'react';
import './App.css';

class App extends Component{
  constructor(props)  {
    super(props);
    this.state = { 
      apiResponse: []
    }; 
    this.getData = this.getData.bind(this);
  }
  componentDidMount() {
    this.getData();
  }

  getData = () => {
    fetch('http://localhost:5000')
      .then(results => results.json())
      .then(console.log)
      .then(results => this.setState({apiResponse: results}, () => {
        console.log('data in state', this.state.apiResponse)
      }))
      .catch(err => console.error(err));
  }
  render()  {
    return (
      <div className="App">
        <h1>Display</h1>
        <h1>{this.state.apiResponse}</h1>
        <h1>Does this work?</h1>
      </div>
    );
  }
}

export default App;

我 运行 在获取 returns 适当的 JSON 对象之后的第一个 console.log,但是 returns 之后的下一个 console.log未定义,并且 {this.state.apiResponse} 不呈现任何内容。

您正在使用 then 方法处理 json 对象,但是您没有 return 某些东西以便下一个 then 作为输入。

如果删除这一行

.then(console.log)

那么应该可以了。

每当您使用 .then() 解析 Promise 时,您都希望将解析传递给下一个回调。 .then(console.log) 打破了这一点。您在下一次回调中没有结果。 详细了解 here .

问题是,当您作为回调传递给 then consol.log 函数时,在您继续 then 链接并期望访问结果之后,您顺便说一下,应该直接调用 then 链,在调用 console.log 之前设置 state ,然后在该回调中调用 return results 像这样

fetch('http://localhost:5000')
  .then(results => results.json()) 
  .then(results => {
      this.setState({apiResponse: results}, () => {
          console.log('data in state', this.state.apiResponse)
      });
      return result;
   })
   .then(console.log);

或者像这样用普通函数替换它

fetch('http://localhost:5000')
  .then(results => results.json())
  .then((results) => {
      console.log(results);
      return results;
  })
  .then(results => {
      this.setState({apiResponse: results}, () => {
          console.log('data in state', this.state.apiResponse)
      });
      return result;
   });

这是您的 Chaining 中的问题,这是一个答案:

The then method returns a Promise which allows for method chaining.

If the function passed as handler to then returns a Promise, an equivalent Promise will be exposed to the subsequent then in the method chain. - MDN

...
      .then(console.log) // here you're not exposing any response
...
  }

补救措施可以是:

...
getData = () => {
    fetch('http://localhost:5000')
      .then(results => {console.log(results); return results.json()})
      .then(results => this.setState({apiResponse: results}, () => {
        console.log('data in state', this.state.apiResponse)
      }))
      .catch(err => console.error(err));
  }
...

    import React, { Component } from 'react';
    import './App.css';
    
    class App extends Component{
      constructor(props)  {
        super(props);
        this.state = { 
          apiResponse: []
        }; 
        this.getData = this.getData.bind(this);
      }
      componentDidMount() {
        this.getData();
      }
    
      getData = () => {
        fetch('http://localhost:5000')
          .then(results => results.json())
          .then(console.log)
          .then(results => this.setState({apiResponse: results}))
          .catch(err => console.error(err));
      }
      render()  {
        return (
          <div className="App">
            <h1>Display</h1>
            <h1>{this.state.apiResponse && 
         this.state.apiResponse.recordSets.map((singleRecord, index)=>           
  singleRecord.map(singleElement => <span> 
              {singleElement.FactoryName}</span>))}</h1>
                <h1>Does this work?</h1>
              </div>
            );
      }
    }
    
    export default App;