【问题标题】:Why is my fetch promise being stored in the prop as empty instead of the json i'm fetching?为什么我的 fetch promise 存储在 prop 中是空的,而不是我正在获取的 json?
【发布时间】:2020-03-05 23:43:22
【问题描述】:

我正在尝试从后端获取 json 来填充前端的表格。什么都没有加载,并且在反应调试工具中它说 table prop 是空的。

我已将异步添加到正在执行提取的函数中,但它似乎仍然在完成之前将 json 传递给道具(不完全确定)。

编辑:代码中缺少行,因为我删除了不相关的内容

在 app.js 中

import React, { Component } from 'react'
import Table from './Table'

class App extends Component {
    render() {
        const repos = getGitHubRepos()
        return (
            <div className="container">
                <Table repoData={repos} />
            </div>
        )   
    }   
}   

async function getGitHubRepos() {
    const response = await fetch('valid url i'm hiding')
    return await response.json()
}   

export default App

在 table.js 中

import React, { Component } from 'react'

class Table extends Component {
    render() {
        const { repoData } = this.props

        return (
            <table>
                <TableHeader />
                <TableBody repoData={repoData} />
            </table>
        )
    }
}


const TableBody = props => {
    const rows = props.repoData.map((row, index) => {
        return (
            <tr key={index}>
                <td>{row.name}</td>
                <td>{row.lang}</td>
            </tr>
        )
    })

    return <tbody>{rows}</tbody>

}

export default Table

我希望输出将 json 的每一位映射到表中,但它没有这样做,因为当它到达 table.js 时 prop 是空的

【问题讨论】:

  • 它不应该是“空的”。 async 函数总是返回一个承诺。 repoData 应该是一个承诺。
  • 每个async 函数都应该使用await 调用。没有它,你打电话给const repos = getGitHubRepos()。此外,每个 await 都应该在 async 函数中
  • 将函数设置为async并在内部使用await只会使函数内部的执行等待解析,它不会阻止外部代码的执行

标签: javascript node.js reactjs promise fetch


【解决方案1】:

将您的获取逻辑移到我建议的组件DidMount 中的Reacts 生命周期方法之一中,您永远不应该在渲染方法中获取任何内容,甚至应该避免在那里进行大量计算.. 获得数据后,我会将其保存在本地组件状态 this.setState({someState: data}) .. 当状态改变时,您的组件将自动重新渲染。你可以从你的组件状态中读取数据 this.state.someState

您从 fetch 中获得 thenable 承诺,您可以使用 .then(function () {}) 来定义获取数据时会发生什么

 function getGitHubRepos() {
     fetch('valid url i'm hiding')
     .then(function (res) {
        this.setState({data: res.data}); // or something similar
      });
  }

【讨论】:

    【解决方案2】:

    您可以在async componentDidMount 方法中执行async 任务:

    class App extends Component {
      constructor() {
        super();
        this.state = { repos: [] };
      }
      async componentDidMount() {
        const repos = await getGitHubRepos();
        this.setState({ repos });
      }
      render() {
        return (
          <div className="container">
            <Table repoData={this.state.repos} />
          </div>
        );
      }
    }
    
    async function getGitHubRepos() {
      const response = await fetch("valid url Im hiding");
      return response.json();
    }
    
    export default App;
    

    所有浏览器都建议async/await 语法为not covered

    【讨论】:

    • 使用这个解决方案我得到一个编译失败的错误'./src/App.js Line 18:34: 'repos' is not defined no-undef',第 18 行是
      ,发生这种情况是否有特定原因?
    • 忘记更改了。 repos 在州可用。所以我们需要使用this.state.repos
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-03
    • 2022-11-16
    • 1970-01-01
    • 2022-01-09
    • 2017-10-26
    相关资源
    最近更新 更多