【问题标题】:Handling promise chain inside a React component constructor在 React 组件构造函数中处理承诺链
【发布时间】:2018-12-06 08:41:17
【问题描述】:

我正在从我的 API 中获取数据,并且需要根据收到的数据构建一个列表。问题是,渲染发生在构造函数中的获取完成之前,因此发送到List 组件的this.todo 恰好是空的。处理这个问题的正确方法是什么?

import React, { Component } from 'react';
import {render} from 'react-dom';
import Header from './header.jsx'
import List from './list.jsx'

class App extends Component {
  constructor(props) {
    super(props)
    this.todos = []

    const url = "http://localhost:3000/api/todos/"
    fetch(url)
    .then(res => res.json())
    .then((data) => {
      this.todos = data;
    })
    .catch(console.error);
  }

  render () {
    return (
      <div>
        <Header />
        <List tasks={this.todos}/>
      </div>
    )
  }
}

render(<App/>, document.getElementById('app'));

【问题讨论】:

  • 将异步操作放在构造函数中通常被认为是不好的做法。这是因为没有一种干净的方式来回传一个 Promise,调用者可以从中确定异步操作何时完成或是否有错误。请参阅Node constructor not blocking 了解三种独立的设计解决方案。我最喜欢的是使用一个工厂函数来创建对象,然后在其上调用一个方法来执行异步操作并返回一个 promise,其解析值是新对象。

标签: javascript reactjs promise


【解决方案1】:

您通常希望向用户发出数据正在加载的信号。您还需要确保区分空数据和未收到的数据。

您还希望这些数据成为组件状态的一部分,而不是类实例本身,以允许组件在接收到数据时重新呈现。

=> this.state.todos 而不是 this.todos

class Example extends React.Component {
  constructor(props) {
    super(props)
    this.state = {
      todos: null
    }
    setTimeout(() => {
      this.setState({
        todos: [1,2,3]
      })
    }, 1000);
  }

  render () {
    return (
      <div>
        {this.state.todos
          ? <div>{this.state.todos.toString()}</div>
          : <div>Loading todos...</div>
        }
      </div>
    )
  }
}

ReactDOM.render(<Example/>, document.getElementById('app'));
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id="app"></div>

这里还有许多其他改进。您可以潜在地缓存数据并在以后显示它,而无需从网络中获取它,然后您可以在幕后获取任何新数据。如果微调器不起作用,您也许可以使用各种占位符。这一切都取决于数据的类型、数据的持久性、用户与其交互的程度、数据的变化程度等。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2020-04-22
  • 2022-11-01
  • 1970-01-01
  • 2019-09-25
  • 2018-02-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多