从回调更新React组件状态



i具有以下反应组件,其中包含状态signed_in。当登录状态更改时,回调触发(使用控制台记录进行了验证(,但是组件不会重新渲染。

class Login extends React.Component {
  constructor(props) {
    super(props);
    this.state = {};
    auth.onAuthStateChanged(function(user) {
      if (user) {
        this.state = { signed_in: true };
        console.log("signed in");
      } else {
        this.state = { signed_in: false };
        console.log("signed out");
      }
    });
  }
  render() {
    return (
      <MDBContainer className="text-center mt-5 pt-5">
        <div>
          {this.state.signed_in ? (
            <div>
              <h5>Please sign-in:</h5>
              <StyledFirebaseAuth uiConfig={uiConfig} firebaseAuth={auth} />
            </div>
          ) : (
            <h5>You are already signed in.</h5>
          )}
        </div>
      </MDBContainer>
    );
  }
}

我怀疑这可能是因为回调函数没有修改组件状态(this.state(?这里的修复是什么?

在基于类的组件的情况下,通过调用组件setState()方法触发重新渲染。

setState()方法接受描述将应用于您的组件状态的对象:

/* Update the signed_in field of your components state to true */
this.setState({ signed_in: true });

通过调用setState()内部反应将状态更改应用于现有组件状态,然后触发重新渲染,此时,在您的组件中可见任何已更改的状态在随后的渲染周期中都可以看到。

对于您的代码,实现这些更改的一种方法是:

class Login extends React.Component {
  constructor(props) {
    super(props);
    this.state = {};
    /* Make arrow function, allowing component's
    setState method to be accessible via "this" */
    auth.onAuthStateChanged((user) => {
      if (user) {
        /* Pass state change to setState() */
        this.setState({ signed_in: true });
        console.log("signed in");
      } else {
        /* Pass state change to setState() */
        this.state = { signed_in: false };
        console.log("signed out");
      }
    });
  }
  render() {
    return (
      <MDBContainer className="text-center mt-5 pt-5">
        <div>
          {this.state.signed_in ? (
            <div>
              <h5>Please sign-in:</h5>
              <StyledFirebaseAuth uiConfig={uiConfig} firebaseAuth={auth} />
            </div>
          ) : (
            <h5>You are already signed in.</h5>
          )}
        </div>
      </MDBContainer>
    );
  }
}

最新更新