激活函数后,父状态不会更新

时间:2018-04-20 14:09:03

标签: javascript reactjs cookies state axios

我已声明父级中的状态,以确定是否已按以下方式登录用户

class App extends Component {
 constructor(props) {
  super(props)
  this.state = {
   isLoggedIn: false
  }
 }

 render() {
  <div>
   {
    (document.cookie && this.state.isLoggedIn) ? (
     <LoggedInHeader/>
    ) : <HomeHeader/>
   }

为了让用户登录,我向api发出了一个axios请求,而api反过来又给了我一个存储在浏览器cookie中的令牌,下面的代码来自我的登录模态组件,我明确更新了在axios请求变为true之后,状态在控制台中更新,正如我所期望的那样,但是当我检查布尔值是真还是假时,它处于原始状态。我知道&#34; setState()不会立即改变this.state&#34;但似乎还无法让状态发生变化。登录表单组件,其下方是应用程序父级的子级。

loginSubmitHandler = (event) => {
event.preventDefault()

const user = "email=" + this.state.email + '&password=' + this.state.password

const instance = axios.create({
  baseURL: 'http://weburl',
  timeout: 1000,
  headers: {'Content-Type': 'application/x-www-form-urlencoded'}
});

instance.post('/login', user)
  .then(res => {
    let d = new Date
    d.setDate(d.getDate() + 30)

    let expires = "expires=" + d

    document.cookie = "sessionname" + "=" + res.data.success.token + expires + ";path=/"
    console.log('changing state')
    this.setState({
      isLoggedIn: true
    }, () => {console.log('New state', this.state)})
  })
  .catch(err => {
    console.log(err, "There was an error")
})}

2 个答案:

答案 0 :(得分:0)

您需要将父状态作为prop传递给子组件。

class Parent extends Component {
    constructor(props){
        super(props);
        this.state = {
            isLoggedIn: false
        }
    }
    render(){
        const {isLoggedIn} = this.state;
        return (
            <Child isLoggedIn={isLoggedIn} />
        )
    }
}

或者您可以在渲染中实现逻辑。

render(){
    const {isLoggedIn} = this.state;
    if(isLoggedIn){
        return <LoggedInHeader />
    }
    return <HomeHeader />
}

答案 1 :(得分:0)

您应该将函数从App组件传递给表单组件,然后触发它。实际上,state是每个组件的内部对象,因此除了使用回调函数之外,它不能直接从另一个组件更新。

例如:

class App extends Component {
    setAuthStatus = status => {
        this.setState({
            isLoggedIn: status,
        })
    }

    constructor(props) {
        super(props)
        this.state = {
            isLoggedIn: false,
        }
    }

    render() {
        return (
            <div>
                {
                    (document.cookie && this.state.isLoggedIn) ?
                        <LoggedInHeader/> : <HomeHeader/>
                }

                <LoginForm setAuthStatus={this.setAuthStatus}/>
            </div>
        )
    }
}

然后在表单中调用

loginSubmitHandler = (event) => {
    event.preventDefault()

    const user = "email=" + this.state.email + '&password=' + this.state.password

    const instance = axios.create({
        baseURL: 'http://weburl',
        timeout: 1000,
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded'
        }
    });

    instance.post('/login', user)
        .then(res => {
            let d = new Date
            d.setDate(d.getDate() + 30)

            let expires = "expires=" + d

            document.cookie = "sessionname" + "=" + res.data.success.token + expires + ";path=/"
            console.log('changing state')
            this.props.setAuthStatus(true)
        })
        .catch(err => {
            console.log(err, "There was an error")
        })
}