Reputation:
I'm fairly new to working with React JS and I'm having a problem pushing items to an array that's part of the components state.
What I'm intending to happen is that when the component mounts the state (allDays array) is updated to list every day in the current month and the next two months. I'm just getting an empty array though. I've checked the loop and that's outputting the dates, they're just not being pushed to the array.
My current JavaScript is:
class CalendarDisplay extends React.Component {
constructor(props) {
super(props);
this.state = { allDays: [] };
}
findDays = () => {
var self = this;
var currentDate = new Date();
var mFormat = currentDate.getFullYear() + '-' + (currentDate.getMonth() + 1) + '-01';
var startBookingDate = moment(mFormat);
var endBookingDate = moment().add(2, 'M').endOf('month');
var currentDate = moment(startBookingDate);
while (currentDate <= endBookingDate) {
self.setState({
allDays: self.state.allDays.concat(moment(currentDate).format('YYYY-MM-DD'))
});
currentDate = moment(currentDate).add(1, 'days');
}
}
componentDidMount = () => {
this.findDays();
console.log(this.state.allDays);
}
render = () => {
return (
<div>Please See the Console Log</div>
)
}
}
ReactDOM.render(
<CalendarDisplay />,
document.getElementById('app')
);
Here's a JS Fiddle of the issue.
I've been reading through the other answers on Stack Overflow and they don't seem to work with this issue. I'm currently trying to use concat technique without success.
Any help would be great.
Upvotes: 2
Views: 1350
Reputation: 2604
Change
self.setState({
allDays: self.state.allDays.concat(moment(currentDate).format('YYYY-MM-DD'))
});
To (editted as per comments)
self.state.allDays.push(moment(currentDate).format('YYYY-MM-DD'));
you need to push the values to the array not concat them.
See JsFiddle
Upvotes: 1
Reputation: 7424
Perfomance-wise, updating state too many times is not a good pattern. Not to mention that it is going to trigger render
a lot.
My suggestion is to keep all values in a temporary variable and then update your state only once.
let days = []
while (currentDate <= endBookingDate) {
days = [...days, moment(currentDate).format('YYYY-MM-DD')]
currentDate = moment(currentDate).add(1, 'days')
}
this.setState({ allDays: days })
Upvotes: 3
Reputation: 2311
I'm pretty sure you can't update the state like that. You should fully build the end array and then update the state. Another benefit of doing it that way is that you will only update the state once (instead of 30/31 times).
findDays = () => {
var month = [];
var self = this;
var currentDate = new Date();
var mFormat = currentDate.getFullYear() + '-' + (currentDate.getMonth() + 1) + '-01';
var startBookingDate = moment(mFormat);
var endBookingDate = moment().add(2, 'M').endOf('month');
var currentDate = moment(startBookingDate);
while (currentDate <= endBookingDate) {
month.push(moment(currentDate).format('YYYY-MM-DD'));
currentDate = moment(currentDate).add(1, 'days');
}
self.setState({ allDays: month );
}
Upvotes: 0