我尝试使用ReactNative创建我的第一个混合应用程序。我的Array.map有问题...
class HomeScreen extends React.Component {
state = {
isLoading: false,
captured: false,
wished: false,
exchanged: false,
data: {}
};
async getPokemonFromApiAsync() {
try {
this.setState({isLoading: true});
let response = await fetch('https://pokeapi.co/api/v2/pokemon/?limit=0&offset=20');
return this.setState({
isLoading: false,
data: await response.json()
});
} catch (error) {
console.error(error);
}
(...)
componentWillMount() {
this.getPokemonFromApiAsync()
}
(...)
result = (result = this.state.data.results) => {
console.log('test', this.state.data);
return (
<View>
(...)
result.map( (item, index) => {
(...)
}
</View>
)
}
}
我不明白,为什么我的函数getPokemonFromApiAsync为空。 iOS模拟器返回TypeError:未定义不是对象(正在评估'result.map')
在添加类似以下的构造函数时:
constructor(props) {
super(props)
this.getPokemonFromApiAsync = This.getPokemonFromApiAsync.bind(this)
}
控制台中有很多错误:
警告:无法在尚未安装的组件上调用%s。这是一项禁止操作的操作,但可能表明您的应用程序中存在错误。而是直接分配给this.state
或在%s组件中使用所需状态定义一个state = {};
类属性。setState,HomeScreen
对我来说,这很正常...
异步Http请求的良好生命周期是什么?
答案 0 :(得分:0)
使用axios库github link
的最佳方法contract AddressBook {
mapping(address => address[]) private _addresses;
mapping(address => mapping(address => string)) private _aliases;
function getAddresses() public view returns (address[]) {
return _addresses[msg.sender];
}
function addAddress(address addr, string _alias) public payable {
_addresses[msg.sender].push(addr);
_aliases[msg.sender][addr] = _alias;
}
function removeAddress(address addr) public payable {
uint length = _addresses[msg.sender].length;
for(uint i = 0; i < length; i++) {
if (addr == _addresses[msg.sender][i]) {
if (1 < _addresses[msg.sender].length && i < length-1) {
_addresses[msg.sender][i] = _addresses[msg.sender][length-1];
}
delete _addresses[msg.sender][length-1];
_addresses[msg.sender].length--;
delete _aliases[msg.sender][addr];
break;
}
}
}
function getAlias(address addr) public view returns (string) {
return _aliases[msg.sender][addr];
}
}
最后,每周下载量超过4,000,000+ Github开始50,000 +
答案 1 :(得分:0)
更好的方法是使用“ then”解决您的诺言时实现状态值。
let response = fetch('https://pokeapi.co/api/v2/pokemon/?limit=0&offset=20')
.then((response) => {
this.setState({
isLoading: false,
data: response.json()
});
});
也许您可以在Promise回调中处理数据(result.map
)并将结果直接插入组件中。
顺便说一句,XHR调用通常以componentDidMount
方法处理。
答案 2 :(得分:0)
您的错误是由您如何将初始data
设置为状态引起的。
您已将其设置为:
state = {
isLoading: false,
captured: false,
wished: false,
exchanged: false,
data: {} // <- here you define it as an object, with no parameters
};
您应该将其设置为带有results参数的对象。因此,您的初始状态应为
state = {
isLoading: false,
captured: false,
wished: false,
exchanged: false,
data: { results: [] } // <- here you should define the results inside the object
};
出现错误的原因:
TypeError: Undefined is not an object (evaluating 'result.map')
是因为在初始渲染中,在获取响应返回之前,它试图在map
之上的this.state.data.results
上不存在。您需要确保状态中的results
有一个初始值。
那应该停止初始错误,但是您必须确保为data
保存的状态也是一个数组,否则您将继续遇到相同的错误。
componentWillMount
已被弃用,您应该使用componentDidMount
。
此外,您在componentWillMount
内部调用异步函数时,还应通过以下方式重构它:
async componentDidMount() {
await this.getPokemonFromApiAsync()
}
这样,直到获取请求完成后才进行安装。
我还将重构您的getPokemonFromApiAsync
,以便您在尝试将其设置为状态之前获得response.json()
。您也不需要return语句,因为this.setState
不返回任何内容。
async getPokemonFromApiAsync() {
try {
this.setState({isLoading: true});
let response = await fetch('https://pokeapi.co/api/v2/pokemon/?limit=0&offset=20');
let data = await response.json(); // get the data
this.setState({
isLoading: false,
data: data // now set it to state
});
} catch (error) {
console.error(error);
}
这是一个非常简单的小吃,显示了https://snack.expo.io/@andypandy/pokemon-fetch的代码正常工作
小吃代码:
export default class App extends React.Component {
state = {
isLoading: false,
captured: false,
wished: false,
exchanged: false,
data: { results: [] } // <- here you should define the results inside the object
};
getPokemonFromApiAsync = async () => {
try {
this.setState({ isLoading: true });
let response = await fetch('https://pokeapi.co/api/v2/pokemon/?limit=0&offset=20');
let data = await response.json(); // get the data
this.setState({
isLoading: false,
data: data // now set it to state
});
} catch (error) {
console.error(error);
}
}
async componentDidMount () {
await this.getPokemonFromApiAsync();
}
render () {
return (
<View style={styles.container}>
{this.state.data.results.map(item => <Text>{item.name}</Text>)}
</View>
);
}
}
答案 3 :(得分:0)
收到错误TypeError: Undefined is not an object (evaluating 'result.map')
的原因是您从result
获取了this.state.data.results
,但是由于数据是异步的,因此在首次呈现时,数据就是{{ 1}}(因为您将其设置为状态),因此{}
为data.result
,并且不能在未定义的地方使用undefined
。
要解决此问题,可以在呈现.map()
之前检查其是否未定义。
data.result