Michał Lach
Michał Lach

Reputation: 1278

force update jQuery fullcalendar, after prop change in React.js

I am struggling with updating jQuery fullcalendar wrapped in React after events prop change.

Here is class containing data & calendar:

export default class Calendar extends Component {
  constructor(props) {
    super(props);
    this.addEvent = this.addEvent.bind(this);
    this.state = {
      events: [
        {
          title: 'Sometitle',
          date: moment(Date.now()),
          allDay: false,
        },
      ],
    };
  }

  addEvent() {
    const date = moment(Date.now()).add(1, 'hour');
    this.setState({
      events: [].concat(this.state.events, [{
        title: 'Sometitle 1',
        date,
        allDay: false,
      }]),
    });
  }

  render() {
    return (
      <div className="allow-scroll">
        <button onClick={this.addEvent}> Add event</button>
        <EmployeesCalendar events={this.state.events} />
      </div>
    );
  }
}

And here is class containing the fullcalendar plugin:

import React, { Component } from 'react';
import jQuery from 'jquery';

require('fullcalendar');

export default class EmployeesCalendar extends Component {
  constructor(props) {
    super(props);
    this.state = {
      events: props.events,
    };
  }

  componentDidMount() {
    const { fullCalendar } = this;

    jQuery(fullCalendar).fullCalendar({
      events: this.state.events,
    });
  }

  componentWillReceiveProps(nextProps, nextState) {
    const { fullCalendar } = this;
    const { events } = nextState;
    this.setState({
      events: nextProps.events,
    }, () => {
      console.log(this.state.events);
      jQuery(fullCalendar).fullCalendar('refetchEventSources', nextProps.event);
    });
  }

  componentWillUnmount() {
    const { fullCalendar } = this;
    jQuery(fullCalendar).fullCalendar('destroy');
  }

  render() {
    return (
      <div ref={(calendar) => { this.fullCalendar = calendar; }} />
    );
  }
}

I have addEvent function that adds new event to array and than I pass it to EmployeesCalendar.

In EmployeesCalendar I update events state in componentWillReceiveProps and than pass it to fullcalendar plugin, forcing to update it. But the fullcalendar never updates.

Any suggestions ?

Upvotes: 0

Views: 2208

Answers (3)

grimmdav
grimmdav

Reputation: 21

The refetchEvents method worked for me, but not until I configured events as a function with a callback rather than as an array.

Instead of componentWillReceiveProps, I used componentDidUpdate, which is fired after state or props actually change. I think that componentWillReceiveProps will work, but it's an earlier event than you need. It gives you an opportunity to change state, which you don't need to do.

  componentDidMount() {
    const { fullCalendar } = this;
    jQuery(fullCalendar).fullCalendar({
      events: (start, end, timezone, callback) => {
        callback(this.state.events);
      },
    });
  }

  componentDidUpdate(nextProps, nextState) {
    const { fullCalendar } = this;
    jQuery(fullCalendar).fullCalendar('refetchEvents');
  }

According to the FullCalendar doc, "FullCalendar will call this function whenever it needs new event data. This is triggered when the user clicks prev/next or switches views." It also appears to be triggered when you run refetchEvents. Maybe rerenderEvents too? I didn't try that one.

Upvotes: 2

pdorns
pdorns

Reputation: 275

Do you mean jQuery(fullCalendar).fullCalendar('refetchEventSources', nextProps.events); instead of jQuery(fullCalendar).fullCalendar('refetchEventSources', nextProps.event); as you have written?

Upvotes: 0

Nedim Hozić
Nedim Hozić

Reputation: 1901

Instead of 'refetchEventSources'

jQuery(fullCalendar).fullCalendar('rerenderEvents');

Upvotes: 0

Related Questions