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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了激活函数后,父状态不会更新相关的知识,希望对你有一定的参考价值。

我已经在父级中声明了状态,以确定是否登录使用,如下所示

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

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

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

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")
})}
答案

您应该从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")
        })
}
另一答案

您需要将父状态作为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 />
}

以上是关于激活函数后,父状态不会更新的主要内容,如果未能解决你的问题,请参考以下文章

从Angular 2中的子组件更新父组件属性

ReactJS - 更新后子级无法访问父级状态

React 子组件在父组件中更新状态后如何将其重置回原始状态

仅在一个片段中隐藏状态栏并在其他片段中显示

反应无状态子组件不会更新父组件中的状态更改

数组状态更新后反应不重新渲染