【问题标题】:Async await and fetch syntax not working in React异步等待和获取语法在 React 中不起作用
【发布时间】:2017-04-04 15:55:57
【问题描述】:

这是我的代码:

export class App extends Component {
    constructor(props) {
        super(props)
    }
    async fetchSport(sport) {
        let headers = new Headers()
        headers.append('key-goes-here', 'pass-goes-here')
        headers.append('Accept', 'application/json')
        let request = new Request('api-url-goes-here' + sport, {headers: headers})
        let data = await fetch(request).then(response => response.json()).then(json => json.players.forward)
        console.log(data) // 'Christopher Brown'
        return data
    }
    render() {
        return (
            <div className='app'>
                <SportPlayers
                    sport={this.fetchSport('soccer')}
                />
            </div>
        )
    }
}

未捕获的错误:对象作为 React 子对象无效(发现:[object 承诺])。如果您打算渲染一组孩子,请使用 数组代替或使用 createFragment(object) 从 反应附加组件。检查 `SportPlayers` 的渲染方法。

我试图弄清楚为什么会出现这个错误。 fetchSport 函数应该返回一个字符串(如 console.log 建议的那样),但似乎是向视图返回了一个承诺。

下面是我的 webpack.config.js:

var webpack = require("webpack");

module.exports = {
    entry: ["babel-polyfill", "./src/index.js"],
    output: {
        path: "/dist/assets",
        filename: "bundle.js",
        publicPath: "assets"
    },
    devServer: {
        inline: true,
        contentBase: "./dist",
        port: 3000 
    },
    module: {
        loaders: [
            {
                test: /\.js$/,
                exclude: /(node_modules)/,
                loader: ["babel-loader", 'babel-loader?presets[]=es2016,presets[]=stage-3,presets[]=react'],
            },
            {
                test:  /\.json$/,
                exclude: /(node_modules)/,
                loader: ["json-loader"]
            },
            {
                test: /\.css$/,
                loader: 'style-loader!css-loader!autoprefixer-loader'
            },
            {
                test: /\.scss$/,
                loader: 'style-loader!css-loader!autoprefixer-loader!sass-loader'
            }
        ]
    }
}

【问题讨论】:

  • 不要从render 调用fetch 方法。此外,fetchSport 返回一个承诺,您不能将其传递给SportPlayers
  • 异步函数 always 返回一个承诺;这就是异步函数的用途。
  • 这就是使用异步等待的危险,人们通常认为他们在编写同步代码,实际上 异步等待 使您可以像编写代码一样编写asynchronous 代码同步代码。也许你应该从学习 es6 生成器的工作原理开始,以充分理解异步等待的概念
  • 顺便说一句,您在函数末尾返回的数据可以使用此代码this.fetchSport('soccer').then(data =&gt; console.log(data))
  • @Bergi @Frxstrem @oliv37 谢谢大家。我没有注意到异步函数总是返回一个承诺。那么,在这种情况下我还能使用fetch 吗?调用它的正确上下文是什么。我是 React 新手。

标签: javascript reactjs asynchronous ecmascript-6 babeljs


【解决方案1】:

正如许多人已经说过的,async 函数将始终返回一个Promise 对象,然后您可以使用.then() 获取其值。

一般来说,如果您需要向服务器发出许多请求,您应该使用状态管理框架,例如Redux。然而,Redux 引入了很多样板。如果您的用例很简单,您可以只使用local UI state 来存储您的调用结果。

类似这样的:

export class App extends Component {
    constructor(props) {
      super(props)
      this.state = { sport: '' }
    }

    componentDidMount() {
      this.fetchSport('soccer').then(sport => this.setState({ sport }))
    }

    async fetchSport(sport) {
        let headers = new Headers()
        headers.append('key-goes-here', 'pass-goes-here')
        headers.append('Accept', 'application/json')
        let request = new Request('api-url-goes-here' + sport, {headers: headers})
        let data = await fetch(request).then(response => response.json()).then(json => json.players.forward)
        console.log(data) // 'Christopher Brown'
        return data
    }

    render() {
        return (
            <div className='app'>
                <SportPlayers
                    sport={this.state.sport}
                />
            </div>
        )
    }
}

【讨论】:

    猜你喜欢
    • 2019-03-17
    • 1970-01-01
    • 2023-04-07
    • 2018-01-02
    • 1970-01-01
    • 2018-01-27
    • 2014-08-17
    相关资源
    最近更新 更多