setState没有被触发

时间:2019-10-18 14:26:09

标签: reactjs

我有以下代码

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("....")

3 个答案:

答案 0 :(得分:2)

使用class methods时,我们应先在bindconstructor。这与this在javascript中的工作方式有关。从this内部访问submit时,它实际上是指submit而不是您的Componentbind这样

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})