我有一个使用AsyncStorage本地保存的参数的提取。但是我的fetch仅在第二次或第三次尝试时返回数据,因此当我尝试在我的渲染上映射数据时,它表示它无法映射未定义的数据。
这是我的AsyncStorage和获取代码:
componentWillMount(){
AsyncStorage.getItem('key').then((codigo)=>{
this.setState({value: JSON.parse(codigo)});
this.getData()
})
}
getData(){
fetch(`URL/portalacv_ws.asmx/GetDetalhesViatura?CarID=${this.state.value}`)
.then((response) => { return response.json()})
.then(res => {
this.setState({data: res})
})
}
这是我在控制台上获得的:
答案 0 :(得分:2)
您遇到的问题是两种方法都是async
。在您的情况下,您应该在获得项目后拨打getData
作为回电。
componentWillMount(){
AsyncStorage.getItem('key').then((codigo)=>{
//This code runs async, so when you call getData, value has not been changed yet (Or at least you cannot be sure).
this.setState({value: JSON.parse(codigo)});
//Printing here this.state.value will help you to understand
this.getData()
})
}
getData(){
fetch(`URL/portalacv_ws.asmx/GetDetalhesViatura?CarID=${this.state.value}`)
.then((response) => { return response.json()})
.then(res => {
this.setState({data: res})
})
}
componentWillMount(){
AsyncStorage.getItem('key').then((codigo)=>{
this.setState({value: JSON.parse(codigo)}, () => {
//Here you are pretty sure that the setState has already done.
this.getData()
});
})
}
getData(){
fetch(`URL/portalacv_ws.asmx/GetDetalhesViatura?CarID=${this.state.value}`)
.then((response) => { return response.json()})
.then(res => {
this.setState({data: res})
})
}
在看完整个组件后,结论是渲染方法在setState之前执行一次,之后执行一次,这就是为什么你第一次没有定义,第二次是你期望的值。
因此,为了解决这种情况,一种可能的方法是在获取完成后通过扩展获取数据和呈现的操作。或多或少,这个想法将是:
export default class Favoritos extends Component {
constructor(props) {
super(props);
this.state = {
value: null,
data: null,
fetching: false
};
//Binding is not needed, but...
this.getData = this.getData.bind(this);
this.onPress = this.onPress.bind(this);
}
componentWillMount(){
this.setState({ fetching: true }, () => {
AsyncStorage.getItem('key').then((codigo)=>{
this.setState({value: JSON.parse(codigo)}, () => {
this.getData()
.then((data) => {
this.setState({
data: data,
fetching: false
})
})
});
})
});
}
getData(){
return fetch(`URL/portalacv_ws.asmx/GetDetalhesViatura?CarID=${this.state.value}`)
.then((response) => { return response.json()})
}
onPress(){
this.setState({ fetching: true }, () => {
this.getData()
.then((data) => {
this.setState({
data: data,
fetching: false
})
})
});
}
render() {
if(this.state.fethcing){
return (
<View style={{ flex: 1, backgroundColor: 'white' }}>
Fetching data...
</View>
);
} else {
return (
<View style={{ flex: 1, backgroundColor: 'white' }}>
<ScrollView>
<TouchableHighlight onPress={this.onPress}>
...
</TouchableHighlight>
<Text>
{this.state.value}
</Text>
</ScrollView>
</View>
);
}
}
}
在上面的代码中,我只留下了有意义的代码,原始代码有更多的代码。