我正在尝试将App组件中的users: []
设置为fetch
的响应。
当我尝试使用this.setState
更改users:
的值时,我的代码停止执行,this.state.users
仍为空。
不太清楚最新情况,我是否错误地使用componentWillMount
? (有人在教程中使用它,我对生命周期方法的正确使用感到有些困惑)
我是这个React malarky的新手。
此外,由于' Expo'没有回应我像疯子一样摇动我的手机,我无法查看错误日志。
import React, {Component} from 'react';
import { StyleSheet, Text, View } from 'react-native';
export default class App extends React.Component {
constructor() {
super();
this.state = {
users: [],
}
}
componentWillMount() {
// Not sure if I'm using this ^ correctly
this._fetchUsers();
}
render() {
const users = this._getUsers();
return (
<View style={styles.container}>
<Text>Users</Text>
<View>
{users}
</View>
</View>
);
}
_fetchUsers() {
fetch('http://api.example.111.111.11.111.xip.io/users')
// This ^ is returning json
.then((response) => {
console.log(1)
// This ^ log is visible
this.setState({users: response._bodyText});
// Code stops executing around here
console.log(2)
// This ^ log is not visible
})
}
_getUsers() {
return this.state.users.map((user) => {
return(<User
name={user.name}
email={user.email}
key={user.id} />);
})
}
}
class User extends React.Component {
render() {
return(
<View className="user">
<Text className="user-name">{this.props.name}</Text>
<Text className="user-email">{this.props.email}</Text>
</View>
)
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
}
});
response._bodyText
返回与此类似的用户对象数组:
[{id:'1', name:'Steve', email:'steve@example.com'},{id:'2', name:'notSteve', email:'notsteve@example.co.uk'.... ect
非常感谢任何帮助。
由于
更新:目前正在重新下载xcode以使应用程序在模拟器上运行,使用expo应用程序时遇到很多问题,即使在保存更改后重建相同的代码,也必须继续重新安装应用程序以运行更改,甚至仍然有问题。应该在45分钟到一个小时内进行另一次更新,感谢目前为止的所有答案。感觉就像我在学习东西 :d
最新更新:好的,问题已经解决,但尚未完全理解。
我的response
看起来像这样:
Response {
13:43:00: "_bodyInit": "[{\"id\":2,\"name\":\"Joe Bloggs\",\"email\":\"joe@example.com\", ........ect]",
13:43:00: "_bodyText": "[{\"id\":2,\"name\":\"Joe Bloggs\",\"email\":\"joe@example.com\", ........ect]
13:43:00: "headers": Headers {
13:43:00: "map": Object { ........... ect
所以使用response._bodyText
给了我一串json,这解释了为什么它不作为一个对象。
正如@Srdjan Cosic所建议的
response.json()
给了我:
Promise {
13:54:17: "_40": 0,
13:54:17: "_55": null,
13:54:17: "_65": 0,
13:54:17: "_72": null,
13:54:17: }
我还没有承诺承诺,所以根本没有理解这一点。
和response.data
给了我undefined
最后,@ {srdjan Cosic再次提出了部分建议的工作this.setState({users: JSON.parse(response._bodyText)})
。
奇怪的是,this.setState({users: JSON.parse(response)})
返回了完全相同的内容,但仍然无效:/
TL; DR - 我已经开始使用componentDidMount(thanks for the advise everyone)
,我的回复json很奇怪,所以必须使用this.setState({users: JSON.parse(response._bodyText)})
将部分json转换为对象。
感谢大家的帮助。
答案 0 :(得分:0)
永远不要在componentWillMount()中使用副作用(如api调用,获取数据或setState等异步调用),就像在首次呈现或装载组件之前一样。在呈现发生之前,不会返回对获取数据的异步调用。因此将this._fetchUsers()放在componentDidMount()。
中让我知道它是否有效)
答案 1 :(得分:0)
首先,根据关于componentWillMount()
https://reactjs.org/docs/react-component.html#componentwillmount的Reacts文档
它说
在安装发生之前调用
componentWillMount()
。它在render()
之前调用,因此在此方法中同步调用setState()
不会触发额外的渲染。通常,我们建议改为使用constructor()
。避免在此方法中引入任何副作用或订阅。对于这些用例,请改用
componentDidMount()
。
这基本上意味着您应该尝试在._fetchUsers()
或constructor()
中呼叫componentDidMount()
。
第二件事,我不确定response._bodyText
是什么,因为我在Fetch上的文档中找不到任何关于它的内容但是如果响应对象是fetch文档中描述的那个,那么你有权访问.body
属性。所以不要这样做
this.setState({users: response._bodyText})
为什么不尝试this.setState({users: JSON.parse(response.body)})
这将解析正文(假设它是你所描述的json格式)并将其转换为javascript对象。
我使用axios,如果我的响应返回一个json,我通常可以使用response.data
访问它,这样也可以用于获取。否则,response.json()
还会在响应变为json https://developer.mozilla.org/en-US/docs/Web/API/Body/json之后返回另一个承诺
答案 2 :(得分:0)
在使用之前,您必须将response
强制转换为json
async _fetchUsers() {
let response = await fetch('http://api.example.111.111.11.111.xip.io/users');
let responseJson = await response.json();
return responseJson.movies;
})
}
componentWillMount() {
let users = this._fetchUsers();
this.setState({ users });
}