简体   繁体   English

React js 状态和生命周期

[英]React js state and lifecycle

componentDidMount() {
    const user = auth.getCurrentUser();
    this.setState({ user });
  }

I have this code, I think this.setState({ user });我有这个代码,我认为this.setState({ user }); takes a little time, if I want to do some checks immidetly like需要一点时间,如果我想立即进行一些检查,例如

<Route
              path="/foo"
              render={props =>
                this.state.user ? (
                  <Bar {...props} />
                ) : (
                  <Redirect to="/login" />
                )
              }
            />

when refreshing the page the user at the beginning is always null.刷新页面时,开头的用户始终为空。 what is the proper solution?什么是正确的解决方案? do I need to set state at constructor ?我需要在constructor设置状态吗? or did I do something wrong?还是我做错了什么?

My account got blocked by some down votes questions, the funny thing is I have to re-edit them, even though I already have the accepted answer.I do not understand what's the point to do this.I am so frustrated by this stackoverflow system.我的帐户被一些否决票问题封锁,有趣的是我必须重新编辑它们,即使我已经接受了答案。我不明白这样做有什么意义。我对这个 stackoverflow 系统感到非常沮丧.

Now, I basically can do nothing but keep editing my questions, and they have all been answered.现在,我基本上只能继续编辑我的问题,它们都得到了回答。 This is ridiculous !!!这是荒唐的 !!!

Yes, you should initialise your state in the constructor.是的,您应该在构造函数中初始化您的状态。

See the React docs example :请参阅React 文档示例

class Clock extends React.Component {
  constructor(props) {
    super(props);
    this.state = {date: new Date()};
  }

  render() {
    return (
      <div>
        <h1>Hello, world!</h1>
        <h2>It is {this.state.date.toLocaleTimeString()}.</h2>
      </div>
    );
  }
}

when refreshing the page the user at the beginning is always null刷新页面时,开头的用户始终为空

@Shubham Khatri did explain it really well, in short, just because the render() function is called before the componentDidMount() , hence, the user is always null. @Shubham Khatri 确实很好地解释了它,简而言之,只是因为render()函数在componentDidMount()之前调用,因此, user始终为空。

Take a look at this: React lifecycle methods diagram看看这个: React 生命周期方法图

React 生命周期方法图

And as you can see that, the proper place for setState should be the contructor() cuz it's called before the render() .正如你所看到的, setState的正确位置应该是contructor()因为它在render()之前被调用。

However, for api calls why componentDidMount is the better place?但是,对于 api 调用,为什么componentDidMount是更好的地方? why we do not do all set up in constructor ?为什么我们不在constructor做所有设置?

I know you're talking about this: https://reactjs.org/docs/faq-ajax.html .我知道你在谈论这个: https : //reactjs.org/docs/faq-ajax.html The document does say that: You should populate data with AJAX calls in the componentDidMount lifecycle method.该文档确实说:您应该在componentDidMount生命周期方法中使用 AJAX 调用填充数据。 This is so you can use setState to update your component when the data is retrieved.这样您就可以在检索数据时使用setState来更新您的组件。

However,in another place , they say:然而,在另一个地方,他们说:

You may call setState() immediately in componentDidMount() .您可以在componentDidMount()立即调用setState() componentDidMount() It will trigger an extra rendering, but it will happen before the browser updates the screen.它会触发额外的渲染,但它会在浏览器更新屏幕之前发生。 This guarantees that even though the render() will be called twice in this case, the user won't see the intermediate state.这保证即使在这种情况下render()将被调用两次,用户也不会看到中间状态。 Use this pattern with caution because it often causes performance issues.请谨慎使用此模式,因为它通常会导致性能问题。 In most cases, you should be able to assign the initial state in the constructor() instead.在大多数情况下,您应该能够在constructor()分配初始状态。 It can, however, be necessary for cases like modals and tooltips when you need to measure a DOM node before rendering something that depends on its size or position.但是,当您需要在渲染取决于其大小或位置的内容之前测量DOM 节点对于模态和工具提示等情况,它可能是必要的

...and also for the case that you need to authenticate because this process depends on the value of the user ( as your design). ...以及您需要进行身份验证的情况,因为此过程取决于user的价值(如您的设计)。

The problem in your code is that, componentDidMount is called after render and by the time your user details are fetched and stored in state, your component is ready to redirect to /login since user wan't available.您的代码中的问题是,在渲染之后调用componentDidMount ,当您的用户详细信息被提取并存储在状态时,您的组件已准备好重定向到/login因为用户不可用。 To solve this issue, you need to fetch user details before the initial render and hence constructor is the ideal place to do it要解决此问题,您需要在初始渲染之前获取user详细信息,因此constructor是执行此操作的理想场所

constructor(props) {
   super(props);
   this.state = {
       user: auth.getCurrentUser()
   }
}

The state goes inside the constructor, but only if you need a constructor (eg:to initialize flags).状态进入构造函数内部,但前提是您需要构造函数(例如:初始化标志)。 If you don't need a constructor you can just initialize the state outside:如果您不需要构造函数,则可以在外部初始化状态:

class MyComponent extends Component {
    state = { myState = [] }

    render() {
        const { myState } = this.state
        return (...)
    }
}

You should use the constructor() to initiate state, componentDidMount() for call functions and componentWillReceiveProps() for setState.您应该使用constructor() 来初始化状态,使用componentDidMount() 来调用函数,使用componentWillReceiveProps() 来初始化setState。

  constructor(props) {
    super(props);
    this.state = {
      firstName: "",
      lastName: ""
    };
  }

  componentDidMount() {
    this.props.userProfile();
  }

  componentWillReceiveProps(nextProps, prevProps) {
    this.setState({
      firstName: nextProps.user.firstName,
      lastName: nextProps.user.lastName
    });
  }

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

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