处理React组件构造函数中的promise链

时间:2018-01-21 00:03:22

标签: javascript reactjs promise

我从我的API获取数据,需要根据收到的数据构建一个列表。问题是,渲染发生的时间早于构造函数中的提取已完成,因此发送到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')); 组件的func makeRequest<T>(endpoint: String, completionHandler: @escaping (ApiContainer<T>?, Error?) -> ()) { let token = DAKeychain.shared["token"] guard let url = URL(string: endpoint+"?token="+token!+"&client_id=60") else { print("Error: cannot create URL") let error = BackendError.urlError(reason: "Could not create URL") completionHandler(nil, error) return } print(url) var urlRequest = URLRequest(url: url) let session = URLSession.shared urlRequest.httpMethod = "GET" urlRequest.addValue("application/json", forHTTPHeaderField: "Content-Type") urlRequest.addValue("application/json", forHTTPHeaderField: "Accept") let task = session.dataTask(with: urlRequest, completionHandler: { (data, response, error) in guard let responseData = data else { print("Error: did not receive data") completionHandler(nil, error) return } guard error == nil else { completionHandler(nil, error!) return } do { let response = try JSONDecoder().decode(ApiContainer<T>.self, from: responseData) completionHandler(response, nil) } catch { print("error trying to convert data to JSON2") print(error) completionHandler(nil, error) } }) task.resume() 恰好为空。处理这个问题的正确方法是什么?

func getContacts() {
    makeRequest(endpoint: "http://blog.local:4711/api/contacts/all",
                completionHandler: { (container : ApiContainer<Contact>?, error : Error?) in
                    if let error = error {
                        print("error calling POST on /getClients")
                        print(error)
                        return
                    }

                    self.tableArray = (container?.result)!

                    DispatchQueue.main.async {
                        self.tableView.reloadData()
                    }
    } )
}

1 个答案:

答案 0 :(得分:1)

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

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

=&GT; this.state.todos代替this.todos

&#13;
&#13;
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'));
&#13;
<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>
&#13;
&#13;
&#13;

这里还有许多其他改进。您可以缓存数据并在以后显示它而无需从网络中获取数据,然后您可以在后台获取任何新数据。如果一个微调器没有工作,你可以使用各种各样的占位符。这完全取决于数据的类型,数据的持久性,用户与之交互的程度,数据的变化程度等等。