首页 > 解决方案 > 无法从我的 ReactJs 站点中的服务器获取数据

问题描述

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

有人帮助我,以便我可以继续

标签: jsonreactjshttpbackend

解决方案


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

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

这很常见,官方 React文档甚至建议在componentDidMount(). 文档还提供了处理此问题的示例。

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

推荐阅读