简体   繁体   English

从回调更新 React 组件状态

[英]Updating React component state from callback

I have the following react component, which contains the state signed_in .我有以下反应组件,其中包含状态signed_in When the login state changes, the callback fires (verified using the console logging), but the component does not re-render.当登录状态更改时,将触发回调(使用控制台日志进行验证),但组件不会重新呈现。

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

I suspect this may be because the callback function isn't modifying the components state ( this.state )?我怀疑这可能是因为回调函数没有修改组件状态( this.state )? What is the fix here?这里有什么修复方法?

In the case of your class based component, a re-render is triggered by calling the components setState() method.对于基于类的组件,通过调用组件setState()方法触发重新渲染。

The setState() method accepts an object describing the state change that will be applied to your components state: setState()方法接受一个描述将应用于组件状态的状态更改的对象:

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

By calling setState() React internally applies the state change to the existing component state and then triggers a re-render, at which point any state changes that have been made will be visible in your components the subsequent render cycle.通过调用setState() React 在内部将状态更改应用于现有组件状态,然后触发重新渲染,此时任何已进行的状态更改都将在您的组件中在随后的渲染周期中可见。

In the case of your code, one way to achieve these changes would be:对于您的代码,实现这些更改的一种方法是:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM