wix / react-native-calendars

React Native Calendar Components 🗓️ 📆
MIT License
9.47k stars 2.94k forks source link

How to manually reload/refresh the agenda #463

Closed LongicornYu closed 3 years ago

LongicornYu commented 6 years ago

I am dynamically loading notes for each day from firebase into the state then load into the agenda. The agenda is not refreshing when I change the content in the state. Only when I reload the page, the changes will show. Is there a way to manually trigger the reload of the agenda? Thanks.

shekharscode commented 6 years ago

Using the basic concept that a component re-renders on a state change, I just tried something. let itemState = this.state.items; this.setState({items:{}}) eventItems = []; //Populate the event Items this.setState({items: itemState});

When I click on the date again, it refreshed the agenda Item. It was not happening before. My use case was that each Item had two buttons for accept and decline events. When I accepted the event, the color of the item should change , but earlier since the agenda item was not reloading, even though I clicked on the date again, the color did not change. It only changed when I clicked on some other date which refreshed the agenda. So it was basically a change in the 'items' of the agenda that triggered it's refresh. But now with the above logic it does work (at least gets refreshed on day click)

LongicornYu commented 6 years ago

In my case, I rendered icons for marked days in the day view and marked periods in the calender view of the agenda dynamically. The data is fetched from firebase database into state then used to render the agenda. I also had a 'mark' buttons rendered for each day in the day view. when clicking on the button for a specific day, it will mark that date. That date should shown as marked in the calendar view and an icon should show up for that day in the day view. I thought changing the state will make the agenda re-render, but looks like it only re-rendered the calendar view, the day in the calendar is shown as marked. But somehow in the day view, the icon is not shown up.

I later found a workaround. I found that selecting a day from the calendar view will re-render the day view. So I manually called the function in the underlying code that handles the selection of a specific day. I called that function for the day that I marked after clicking the mark button, so that will update the day view for me.

gabriel-TheCode commented 6 years ago

Same problem https://github.com/wix/react-native-calendars/issues/463#issuecomment-389714895

onemoredayApp commented 5 years ago

Hi, I've same problem, i've this code:

state = { 
        days: {
            '2018-11-26': {selected: true, selectedColor: 'red'},
            '2018-11-27': { selected: true, selectedColor: 'red'},
            '2018-11-28': { selected: true, selectedColor: 'red'},
        }
    }
removeDay = (date) => {
        var newDate = this.state.days;
        if(newDate[date].selected) {
            newDate[date].selected = false;
        } else {
            newDate[date].selected = true;
        }
        this.setState({ days: newDate })
        console.log(this.state.days)
    }
<Calendar
                                markedDates={
                                    this.state.days
                                }
                                onDayPress={(day)=>{ this.removeDay(day.dateString)}}
                                markingType={'multi-dot'}
                                minDate={'2018-11-26'}
                                maxDate={'2018-11-28'}
                            />

The code works well but the calendar not update on click!

MultiformMusic commented 5 years ago

I've searched about 2 hours before finding the solution for me, based on the exemple here

https://github.com/wix/react-native-calendars/blob/master/example/src/screens/agenda.js

When i save my new item in database and refresh my state the agenda doesn't refresh, to make refresh to work:

--- My state

this.state = { items: {}, // The items show by Agenda allAgendaDates: {} // My items datas from database };

--- My function witch add item in database and refresh agenda

validateAddItem = () => {

// here some code to add items infos in my database, not really important

// after saving my new item to databse i do
// reload all my datas
const allAgendaDates= RealmHelper.getAllAgendaDates();  

// update the state this.setState({ allAgendaDates: allAgendaDates, items: {} }); // and call again loaditems function witch is use by agenda to refresh this.loadItems(day); }

--- My loaditems (adapted from loaditems of example agenda.js)

allAgendaDates is object structure from database containing all the datas to construct the items used by Agenda component

loadItems(day) {

this.state.timeStampItemClicked = day.timestamp;

setTimeout(() => {
  for (let i = -200; i < 300; i++) {
    const time = day.timestamp + i * 24 * 60 * 60 * 1000;
    const strTime = this.timeToString(time);
    if (!this.state.items[strTime]) {
      this.state.items[strTime] = [];
      if (this.state.allAgendaDates.has(strTime)) {
        for (let i = 0; i<this.state.allAgendaDates.get(strTime).length; i++) {
          this.state.items[strTime].push({
            title: this.state.allAgendaDates.get(strTime)[i].title,
            time: AgendaHelper.convertScheduleTimestampToHour(this.state.allAgendaDates.get(strTime)[i].scheduleTimeStamp),
            description: this.state.allAgendaDates.get(strTime)[i].description,
            dateItem: strTime,
            activity: this.state.allAgendaDates.get(strTime)[i].activity,
          });
        }
      }
    }
  }
  //console.log(this.state.items);
  const newItems = {};
  Object.keys(this.state.items).forEach(key => {newItems[key] = this.state.items[key];});
  this.setState({
    items: newItems
  });
}, 1000);

}

budo60 commented 5 years ago

reset items {} and call loadItems() worked for me too, im wondering if there is a possibility to re-render only one day of agenda and not all of them, if anyone got an idea this possibilty would be great

luisiacc commented 4 years ago

I have found a way to do this by using hooks, the thing is in setting items to an empty object {} or null or really anything of your preference, and use an effect to get when items are setted to this value, then load the items. This works for me:

...
useEffect(() => {
  if (items === null) {
    loadItems()
  }
}, [items])

const reloadAgenda = () => {
  setItems(null)
}
...
stale[bot] commented 4 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.