我有以下代码
Possible Unhandled Promise Rejection (id: 0):
TypeError: Cannot read property 'data' of undefined
at LoginScreen.handleSignIn$ (blob:http://localhost:8081/43e70a76-bca3-42a1-8a1f-44f14f5d8aeb:87093:55)
at tryCatch (blob:http://localhost:8081/43e70a76-bca3-42a1-8a1f-44f14f5d8aeb:21953:19)
at Generator.invoke [as _invoke] (blob:http://localhost:8081/43e70a76-bca3-42a1-8a1f-44f14f5d8aeb:22128:24)
at Generator.prototype.(anonymous function) [as next] (blob:http://localhost:8081/43e70a76-bca3-42a1-8a1f-44f14f5d8aeb:21996:23)
at tryCatch (blob:http://localhost:8081/43e70a76-bca3-42a1-8a1f-44f14f5d8aeb:21953:19)
at invoke (blob:http://localhost:8081/43e70a76-bca3-42a1-8a1f-44f14f5d8aeb:22029:22)
at blob:http://localhost:8081/43e70a76-bca3-42a1-8a1f-44f14f5d8aeb:22039:15
at tryCallOne (blob:http://localhost:8081/43e70a76-bca3-42a1-8a1f-44f14f5d8aeb:23231:14)
at blob:http://localhost:8081/43e70a76-bca3-42a1-8a1f-44f14f5d8aeb:23332:17
at blob:http://localhost:8081/43e70a76-bca3-42a1-8a1f-44f14f5d8aeb:24654:21
setState由于某种原因未触发。有人可以帮忙吗?
这是代码
setTimeout(() => {
this.setState({loading: true});
}, 0);
axos.post("....")
答案 0 :(得分:2)
使用class methods
时,我们应先在bind
中constructor
。这与this
在javascript中的工作方式有关。从this
内部访问submit
时,它实际上是指submit
而不是您的Component
。 bind
这样
class Foo extends React.Component{
constructor(props){
super(props)
this.submit = this.submit.bind(this)
}
submit(e){
//now this refers to Foo's instance
}
}
或者您可以使用具有arrow functions
的{{1}}
lexical this
答案 1 :(得分:1)
setTimeout(() => {
this.setState({loading: true});
}, 0);
以0调用setTimeout
并不意味着立即处理回调。
在调用堆栈为空之前,将不会处理回调。
以下代码对此进行了说明:(您将首先看到循环中的值,只有在看到now
之后)
setTimeout(function() {
console.log('now');
}, 0);
for (i = 0; i < 10; i++) {
console.log(i);
}
答案 2 :(得分:0)
如上所述,您需要将提交绑定到构造函数中,将其定义为箭头函数,或者使用回调箭头函数内联调用它。
将其定义为箭头功能通常是“最简单”的方法,但在这种情况下所有方法都可以使用
更改:
std::map
收件人:
submit(ev) {
/* submit code*/
}
然后您可以通过简单地添加诸如按钮之类的道具来使用它:
submit = (ev) =>{
/* submit code*/
}
或嵌入式箭头功能:
<button onClick={this.onSubmit}>Click Me</button>
此外:
拥有用户后,您需要更新加载状态:
<button onClick={(ev)=>this.onSubmit(ev)}>Click Me</button>
请记住,setTimeout和setState都不会直接应用,而是会进入队列(您正在将setTimeout添加到队列中,并且在调用setTimeout时,您会将setState添加到队列中进一步延迟了setState)。
如果需要确保代码在setState调用之后发生,则应提供一个回调函数:
if (user) {
this.setState({loading: false});
//...rest of code
}
我认为:您可能希望将用户状态初始化为:
setState((prevState)=>{
return {someState}
},()=>{
//code to execute after setState is executed
})
然后在身份验证流程中,如果有用户,则使用state={
user:{notLoaded:true}
}
;如果找不到用户,则使用setState({user})
;如果有错误,则使用setState({user:null})
。
这降低了状态管理的复杂性,而无需在渲染函数中添加单独的错误/加载状态:
setState({user:{error})