我是一个新的本机反应,我不能理解这种行为。在异步函数中,我将加载布尔值设置为api调用之前的状态。现在奇怪的是:在收到响应后,我不能将加载布尔值设置回false。它只是一直在setState函数中等待,而没有到达回调。
我已经尝试在多次调用中对每个值执行setState。或者全部在一个函数调用中。我还尝试将整个响应分配给state。在react native中,我可以在从后端获取响应后对其进行控制台日志记录。此外,我还可以在保留加载布尔值(到达回调)时将响应分配给状态。但是,当试图将加载布尔值重新设置为false时,就不是这样了。提示(可能):在json响应中,我包含了一个数组。当省略数组时(不将其赋值给state),它的行为就像它应该的那样……请帮帮我!
// here my mistery
export default class App extends React.Component {
constructor(props) {
super(props);
this.state = {
loading: false,
}
}
async onLogin() {
try {
this.setState({ loading: true }, function () {
console.log('loading is:' + this.state.loading)
}); //works great
const { name, password } = this.state;
//here the api call
const response =
await fetch(`http://10.0.2.2:3000/api/login/${name}&${password}`);
const answer = await response.json();
if (answer.user == 'OK') {
//now the strange function-call
this.setState({
tickets: answer.tickets, //this is the array..!
title: answer.event.title,
token: answer.token.token,
tokenDa: true,
//loading: false, //only reaching callback when commenting that out
}, function () {
console.log('tickets are :' + this.state.tickets[0].kategorie)
})
// same behaviour here
// this.setState({loading: false}, function(){
// console.log('loading ist ' + this.state.loading);
// });
}
}
catch{
console.log('in CATCH ERROR')
}
}
// here also the render function in case that matters:
render() {
if (this.state.loading) {
return (
<View style={styles.container}>
<ActivityIndicator size='large' />
</View>
);
}
return this.state.tokenDa ? (
<View style={styles.container}>
<Text>Event Title : {this.state.title} </Text>
<Button
title={'scan'}
style={styles.input}
/>
{this.state.tickets.map((ticket, i) => (
<div key={i}>
<Text >TicketKategorie : {ticket.kategorie}</Text>
<Text > Datum und Türöffnung {ticket.gueltig_am}</Text>
<Text >Verkauft {ticket.verkauft}</Text>
<Text >Eingescannt {ticket.abbgebucht}</Text>
</div>
))}
</View>
) : (
<View style={styles.container}>
<TextInput
value={this.state.name}
onChangeText={(name) => this.setState({ name })}
placeholder={'Username'}
style={styles.input}
/>
<TextInput
value={this.state.password}
onChangeText={(password) => this.setState({ password })}
placeholder={'Password'}
secureTextEntry={true}
style={styles.input}
/>
<Button
title={'Login'}
style={styles.input}
onPress={this.onLogin.bind(this)}
/>
</View>
)
};
};结果是:由于加载属性而导致的加载屏幕,我不能将该属性设置回false。为什么会发生这种情况!?
发布于 2019-05-21 01:07:44
您需要将剩余的代码包装在第一个setState的回调中,如下所示...
this.setState({ loading: true }, async function () {
const { name, password } = this.state;
const response =
await fetch(`http://10.0.2.2:3000/api/login/${name}&${password}`);
const answer = response.json();
if (answer.user == 'OK') {
this.setState({
tickets: answer.tickets, //this is the array..!
title: answer.event.title,
token: answer.token.token,
tokenDa: true,
loading: false
});
}
});发布于 2019-05-21 01:03:28
正如您可能已经推断的那样,您的setStates的异步性质存在问题。为了解决这个问题,我们可以创建另一个函数来处理实际的API请求,并在第一个set-state的回调中使用它。
setLoading = () => {
this.setState({ loading: true }, () => this.onLogin())
}
onLogin = async () => {
const { name, password } = this.state;
//here the api call
const response = await fetch(`http://10.0.2.2:3000/api/login/${name}&${password}`);
const answer = await response.json();
if (answer.user == 'OK') {
this.setState({
tickets: answer.ticketsm
title: answer.event.title,
token: answer.token.token,
tokenDa: true,
loading: false
}, function () {
console.log('tickets are :' + this.state.tickets[0].kategorie)
})
}https://stackoverflow.com/questions/56224780
复制相似问题