[英]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 生命周期方法图
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 inconstructor
?为什么我们不在
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 incomponentDidMount()
.您可以在
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.