我从我的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()
}
} )
}
答案 0 :(得分:1)
您通常希望向用户提供数据正在加载的信号。您还需要确保区分空数据和未收到的数据。
您还希望此数据是组件状态的一部分,而不是类实例本身,以允许组件在接收数据时重新呈现。
=&GT; 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'));
&#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;
这里还有许多其他改进。您可以缓存数据并在以后显示它而无需从网络中获取数据,然后您可以在后台获取任何新数据。如果一个微调器没有工作,你可以使用各种各样的占位符。这完全取决于数据的类型,数据的持久性,用户与之交互的程度,数据的变化程度等等。