开发者问题收集

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

2021-04-21
52

从 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>
    );
  }
}

有人帮助我,这样我就可以继续

2个回答

正如 Dave Newton 在评论中指出的那样,渲染在请求完成之前触发。这是正常的,你只需要正确处理它。

如果你看到这个 codesandbox 的控制台日志,你可以看到最初 this.state.datas 只是一个空数组 [] - 因此任何访问 this.state.datas[0].description 的尝试都将是 undefined 。仅当请求完成并且状态更新之后,日志才会显示检索到的数据 - 这是因为根据 React Component mount 生命周期 render()componentDidMount() 之前调用,并且请求是异步的。

这是非常常见的,甚至官方 React 文档 都建议在 componentDidMount() 中进行 HTTP 调用。该文档还提供了一个 示例 来处理此问题。

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>
    );
  }
}
justarandomguy
2021-04-21

您的数据状态最初是一个空数组,直到您的 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>
    );
  }
}
Rob Terrell
2021-04-21