React-native-calendars: Changing state on onMonthChange doesn't move to the next/prev month

Created on 16 Jul 2017  路  8Comments  路  Source: wix/react-native-calendars

I'm trying to show the busy days in the calendar using the markedDates property. For the month I'm currently showing I build the markedDays hashtable dynamically from a SQLite database.
When I click the next arrow in the calendar I use onMonthChange to call the method that updates the markedDates list. The list is updated correctly, however the month doesn't move to the next.
I believe I was able to isolate the issue using the code provided in the example. Here's an excerpt of ./example/src/screens/calendar.js with my changes:

`export default class CalendarsScreen extends Component {
constructor(props) {
super(props);
this.state = {
markedDates :{
'2017-07-24': {selected: true, marked: true},
'2017-07-25': {marked: true},
'2017-07-30': {marked: true},
}
};
this.onDayPress = this.onDayPress.bind(this);
}

monthChange(month) {
console.log('month changed2',month);
this.setState({
markedDates :{
'2017-07-01': {selected: true, marked: true},
'2017-07-02': {marked: true},
}
});

}
render() {
return (

onDayPress={this.onDayPress}
onMonthChange={(month) => {this.monthChange.bind(this)(month)}}
style={styles.calendar}
current={'2017-07-17'}
hideExtraDays
markedDates={ this.state.markedDates}
`

If I comment out the "setState" call on the monthChange method, the next/prev arrows work correctly. However if I uncomment the setState, the month doesn't change when the arrows are clicked.

Great work btw!

Bug report

Most helpful comment

set state causes rerender of calendar, since you current does not match the date in calendar it is being reset to current. If you want to start from older month you can set current as older month but as month changes also update current value:

monthChange(month) {
 this.setState({currentdate: month})
}

All 8 comments

I solved the problem by changing method updateMonth on src/calendar/index.js to this:

updateMonth(day, doNotTriggerListeners) { if (day.toString('yyyy MM') === this.state.currentMonth.toString('yyyy MM')) { return; } if (!doNotTriggerListeners) { const currMont = day.clone(); if (this.props.onMonthChange) { this.props.onMonthChange(xdateToData(currMont)); } if (this.props.onVisibleMonthsChange) { this.props.onVisibleMonthsChange([xdateToData(currMont)]); } } this.setState({ currentMonth: day.clone() }) }
If you are OK I can get you a PR
Thanks!

please do so that I can see a diff

Hi sorry I gave you the wrong answer. I actually got it to work by commenting out the method componentWillReceiveProps in src/calendar/index.js . This method is resetting the currentMonth when a current date is provided overriding the next/prev arrow behavior. The current day behavior is already covered by the constructor. Please let me know if I'm missing something

you have current prop hardcoded thats why it always resets to that month

Hi, thanks for the feedback.
I need to be able to navigate through the months while keeping my current date fixed.
I made another example using props and came up with the same results (blocked month arrows)
Here's the short version:
```
export default class CalendarModal extends React.Component {
constructor(props) {
super(props);
this.state = {
currentdate:props.date,
text:'',
}
}

monthChange(month) {
this.setState({text:'This state change blocks month change'})
}

render() {
return (
current={this.state.currentdate }
onMonthChange={(month) => {this.monthChange.bind(this)(month)}}
/>
{this.state.text}

)}
}

This component is called from the main app like this
modalVisible={true}
date={'2017-11-02'}
/>
```

If I remove the setState sentence in monthChange, it all works fine.
Please advise on what I am doing wrong.

Thanks again!

set state causes rerender of calendar, since you current does not match the date in calendar it is being reset to current. If you want to start from older month you can set current as older month but as month changes also update current value:

monthChange(month) {
 this.setState({currentdate: month})
}

Thanks for the clarification.
Great job on the calendar it looks really good especially the Agenda.

thanks!

Was this page helpful?
0 / 5 - 0 ratings

Related issues

dobiedad picture dobiedad  路  4Comments

ercpereda picture ercpereda  路  4Comments

henrikra picture henrikra  路  3Comments

matieux picture matieux  路  4Comments

moiiiiit picture moiiiiit  路  4Comments