无法从我的 ReactJs 站点中的服务器获取数据

Not able to fetch data from server in my ReactJs site

从 JSON

获取数据时出现未定义数据类型错误

找了很多地方都没有找到合适的答案

import SavedData from "./SavedData";

export default class Saved extends React.Component {
  constructor() {
    super();
    this.state = {
      loading: true,
      datas: [],
    };
  }

  async componentDidMount() {
    const url = "https://todo-list-site.herokuapp.com/todo-data";
    const response = await fetch(url);
    const todoData = response.json().then((res) => {
      this.setState({ datas: res });
    });
  }

  render() {
    console.log(this.state.datas[0].description);   //not able to get data
    return (
      <div>
        {/* {this.state.datas.map((items) => (
          <SavedData
            key={items.countTodo}
            title={items.title}
            desc={items.desc}
          />
        ))} */}
      </div>
    );
  }
}

有人帮助我,这样我才能继续

您的数据状态最初是一个空数组,直到您的 componentDidMount 触发并设置状态。因此,在设置状态之前,您的控制台日志将是未定义的。为了解决这个问题,您必须等待 this.state.datas[0] 为真,然后才能访问数组中的第一个对象描述。以下代码似乎按预期工作

import React from "react";

export default class Saved extends React.Component {
  constructor() {
    super();
    this.state = {
      loading: true,
      datas: []
    };
  }

  async componentDidMount() {
    const url = "https://todo-list-site.herokuapp.com/todo-data";
    const response = await fetch(url);
    response.json().then((res) => {
      this.setState({ datas: res });
    });
  }

  render() {
    console.log(this.state.datas[0] && this.state.datas[0].description);
    return (
      <div>
        {this.state.datas.map((items, i) => (
          <div key={i}>
            <div> title={items.title}</div>
            <div> desc={items.description}</div>
          </div>
        ))}
      </div>
    );
  }
}

就像 Dave Newton 在评论中指出的那样,渲染是在请求完成之前触发的。这是正常现象,您只需妥善处理即可。

如果您看到 React Component 的此 codesandbox, you can see that initially this.state.datas is just an empty array [] - so any attempt to access this.state.datas[0].description will be undefined. Only after the state is updated when the request completes, the logs show the data retrieved - this is because according to the mount lifecycle 的控制台日志,则 render()componentDidMount() 之前被调用并且请求是异步的。

这很常见,官方 React docs to make HTTP calls in componentDidMount(). The docs also has provided an example 甚至推荐它来处理这个问题。

import SavedData from "./SavedData";

export default class Saved extends React.Component {
  constructor() {
    super();
    this.state = {
      loading: true,  // we initially set this to true
      datas: [],
    };
  }

  async componentDidMount() {
    const url = "https://todo-list-site.herokuapp.com/todo-data";
    const response = await fetch(url);
    const todoData = response.json().then((res) => {
      this.setState({
        datas: res,
        loading: false  // when the request is complete, we set this to false
      });
    });
  }

  render() {
    if (this.state.loading) {
      // during the first render, loading will be true and we
      // can return a loading message or a spinner
      return (
        <div>Loading...</div>
      );
    }

    // when render is called after the state update, loading will be false
    // and this.state.datas will have the fetched data
    console.log(this.state.datas[0].description);
    return (
      <div>
        {this.state.datas.map((items) => (
          <SavedData
            key={items.countTodo}
            title={items.title}
            desc={items.desc}
          />
        ))}
      </div>
    );
  }
}