[英]How to access state set through a function which is called in ComponentDidMount()
I have a function called calendarLogicHandler()
which sets state
, spreading a whole month into it.我有一个名为
calendarLogicHandler()
的函数,它设置state
,将整个月扩展到它。 I called it inside componentDidMount()
.我在
componentDidMount()
调用了它。
the state
set works on the calendar app
which I am working on. state
集适用于我正在开发的日历app
。 This calendar tool will be part of a yoga classes app
.这个日历工具将成为瑜伽课程
app
。
then on the week View Mode of the tool, which displays all of events of a single week, I call weekAgendaLogicHandler()
, which filters the current week of the current month and displays it on the app
.然后在显示一周所有事件的工具的周视图模式上,我调用
weekAgendaLogicHandler()
,它过滤当月的当前周并将其显示在app
。 The state
for the current week and current month are manipulated further ahead in my logic, but there is no point in displaying this here.当前周和当前月的
state
在我的逻辑中被进一步操纵,但在这里显示它没有意义。
The issue is:问题是:
I cannot access this.state.currrentMonth
on ComponentDidMount()
and somehow I see that when I try to console.log(this.state.currentMonth)
on render()
I see that it renders this.state.currentMonth
twice blank, then, on the third re-rendering it finally gets the this.state.currentMonth
set by calendarLogicHandler()
.我无法在
ComponentDidMount()
上访问this.state.currrentMonth
并且不知何故我看到当我尝试在render()
上console.log(this.state.currentMonth)
render()
我看到它呈现this.state.currentMonth
两次空白,然后,在第三次重新渲染时,它最终获得了由calendarLogicHandler()
设置的this.state.currentMonth
。
current month in render() []
current month in render() []
getting current month in componentDidMount []
current month in render() [Array[7], Array[7], Array[7], Array[7], Array[7]]
current month in render() [Array[7], Array[7], Array[7], Array[7], Array[7]]
[]
How could I properly use this function so I can call weekAgendaLogicHandler()
without having it called inside the callback
function
of this.setState({currentMonth})
, and setting my state before the rendering phase, in other words, before componentdidmount
?我怎样才能正确使用这个函数,这样我就可以调用
weekAgendaLogicHandler()
而不在this.setState({currentMonth})
的callback
function
中callback
它,并在渲染阶段之前设置我的状态,换句话说,在componentdidmount
之前?
the code is here and below:代码在这里和下面:
import React from "react";
import "./styles.css";
export default class App extends React.Component {
state = {
currentWeek: [],
currentMonth: [],
monthGetter: new Date().getMonth(),
yearGetter: new Date().getFullYear()
};
componentDidMount() {
this.calendarLogicHandler();
this.weekAgendaLogicHandler();
console.log(
"getting current month in componentDidMount",
this.state.currentMonth
);
}
weekAgendaLogicHandler = () => {
let currentWeek = this.state.currentMonth
.filter(week => week.includes(new Date().setHours(0, 0, 0, 0)))
.flat();
this.setState({ currentWeek }, () => console.log(this.state.currentWeek));
};
calendarLogicHandler = () => {
const oneDay = 86400000;
const lastDayOfTheMonth = new Date(
this.state.yearGetter,
this.state.monthGetter + 1,
0
).getDate();
let currentMonth = [
new Date(this.state.yearGetter, this.state.monthGetter, 1).valueOf()
]; //starts on month day 1
for (let i = 1; i < lastDayOfTheMonth; i++) {
//push the entire month
currentMonth.push(Math.max.apply(null, currentMonth) + oneDay);
}
//localize the first date of the month dates array and check what day of the week it is
//spread the days of the week, which are the remaining days of prev month to fill calendar first week
for (let i = new Date(Math.min(...currentMonth)).getDay(); i > 0; i--) {
currentMonth.unshift(Math.min.apply(null, currentMonth) - oneDay);
}
//spread the days of the week, which are the remaining days of prev month to fill calendar last week
for (let i = new Date(Math.max(...currentMonth)).getDay(); i < 6; i++) {
currentMonth.push(Math.max.apply(null, currentMonth) + oneDay);
}
let monthInWeeks = [];
for (let i = 0; i < currentMonth.length; i += 7) {
let chunk = currentMonth.slice(i, i + 7);
monthInWeeks.push(chunk);
}
currentMonth = monthInWeeks;
this.setState({ currentMonth });
};
render() {
console.log("current month in render()", this.state.currentMonth);
return (
<div className="App">
<h1>Testing componentDidMount</h1>
</div>
);
}
}
This is the way how react works.这就是反应的工作方式。
Lifecycle render()
method gets called on every update. Lifecycle
render()
方法在每次更新时都会被调用。 And also it gets called before componentDidMount
.而且它在
componentDidMount
之前被调用。 According to the lifecycle name componentDidMount
means function getting called after component got mounted.根据生命周期名称
componentDidMount
表示在组件挂载后调用函数。 And since component got already mounted
, so render()
method already got called before componentDidMount
method.由于组件已经
mounted
,因此在componentDidMount
方法之前已经调用了render()
方法。
So, first time when you are getting blank data ie, before componentDidMount
, render()
is getting called with the initial state ie, []
因此,当您第一次获取空白数据时,即在
componentDidMount
之前, render()
使用初始状态调用render()
,即[]
Second time again, probably something is getting updated probably in weekAgendaLogicHandler()
function due to which again render()
is getting called with blank []
array ie., the initial state.第二次,可能会在
weekAgendaLogicHandler()
函数中更新某些内容,因为再次使用空白[]
数组调用render()
,即初始状态。
Now, third time , this.setState is happening state is getting updated and then on render()
you are getting the required array.现在,第三次,this.setState 正在发生状态正在更新,然后在
render()
您将获得所需的数组。
So, this is how render()
lifecycle method works.所以,这就是
render()
生命周期方法的工作原理。
Now, if you want to use render
only with the data and not null
data.现在,如果您只想对数据而不是
null
数据使用render
。 Then , you can show some kind of loader.然后,您可以显示某种加载程序。
ie, IE,
render(){
if(this.state.currentMonth.length){
return(
<div className="App">
<h1>Testing componentDidMount</h1>
</div>
)
}
else{
return(
<p>Loading data...</p>
)
}
}
Not sure that I understand what do you want to accomplish?不确定我是否理解您想要完成的任务? Maybe to see how state looks like after
this.calendarLogicHandler(); this.weekAgendaLogicHandler();
也许看看
this.calendarLogicHandler(); this.weekAgendaLogicHandler();
之后状态的样子this.calendarLogicHandler(); this.weekAgendaLogicHandler();
? ?
If that is the case use componentDidUpdate
.如果是这种情况,请使用
componentDidUpdate
。 In componentDidMount
you can only see how state looks like at the time component get mounted in the dom.在
componentDidMount
您只能看到组件在 dom 中安装时的状态。
So it doesn't matter that you are doing console.log
in this order:因此,您按以下顺序执行
console.log
并不重要:
this.calendarLogicHandler();
this.weekAgendaLogicHandler();
console.log(
"getting current month in componentDidMount",
this.state.currentMonth
);
... you are still logging the state as it was before calendarLogicHandler
& weekAgendaLogicHandler
are fired. ...您仍在记录在
calendarLogicHandler
和weekAgendaLogicHandler
被触发之前的状态。
If you don't wan't to call weekAgendaLogicHandler
in componentDidMount
(because you don't already have state in shape you need), than you can use something like this:如果你不想在
componentDidMount
调用weekAgendaLogicHandler
(因为你还没有你需要的状态),那么你可以使用这样的东西:
componentDidUpdate(prevProps, prevState) {
if(/* check that state is previously updated by `calendarLogicHandler` */) {
this.weekAgendaLogicHandler();
}
}
But, using a lot timing (hooking into lifecycle events) can make your code unnecessary complex.但是,使用大量时间(挂钩生命周期事件)会使您的代码变得不必要的复杂。 If I were you, would choose to use
setState
callback to call this.weekAgendaLogicHandler()
;如果我是你,会选择使用
setState
回调来调用this.weekAgendaLogicHandler()
;
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.