从回调更新React组件状态

时间:2019-07-05 04:05:54

标签: javascript reactjs jsx

我有以下反应成分,其中包含状态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)吗?解决的方法是什么?

1 个答案:

答案 0 :(得分:2)

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

setState()方法接受一个对象,该对象描述将应用于组件状态的状态更改:

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

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

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

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