0

I am trying to implement react big calendar however I am having an issue with adding an event and using set state to update the event.I created a my calendar component then use the handle select function to take the new event and set the state but im not sure how I can set the state correctly. The documentation for set state uses render but I don't use render to display the calendar. Im not sure where I would need the constructor method or what I might be missing.

the current error is

TypeError: Cannot read property 'setState' of undefined

import React, { useState } from "react";
import "react-big-calendar/lib/css/react-big-calendar.css";
import Navigation from "../components/Navigation";
import events from "./events";
import { Calendar, momentLocalizer } from "react-big-calendar";
import moment from "moment";

const localizer = momentLocalizer(moment);

const handleSelect = ({ start, end }) => {
  const title = window.prompt("New Event name");

  alert("title " + title);

  if (title) {
    this.setState({
      events: [
        this.state.events,
        {
          start,
          end,
          title,
        },
      ],
    });

    console.log(events);
  }
};

const MyCalendar = (props) => (
  <div>
    <Navigation />
    <Calendar
      selectable
      localizer={localizer}
      events={events}
      popup
      startAccessor="start"
      endAccessor="end"
      style={{ height: 700 }}
      onSelectSlot={handleSelect}
    />
  </div>
);
export default MyCalendar;

Los
  • 3
  • 2
  • You don't use `this` in functional components. `const [events, setEvents] = useState(initial value here)` – Joel Hager Jul 08 '21 at 07:08
  • `this` is simply undefined in React function components, use the `useState` React hook instead. `handleSelect` should also be declared ***inside*** the component it's updating state for. What isn't clear is ***where*** you even use this state you are attempting to set. – Drew Reese Jul 08 '21 at 07:09

1 Answers1

0

The keyword this does nothing in the world of functional programming. It is a concept of OOP. Don't mix them up.

Instead, do the following

import { useState } from "react";
import moment from "moment"; // bad practice BTW, moment is huge. You should only import the part you need instead of the entire package

const MyCalendar = props => {
  const [events, setEvents] = useState([]);

  const handleSelect = ({ start, end }) => {
    const title = window.prompt("New Event name");

    alert("title " + title);

    if (title) {
      // add a new event
      setEvents(events => ([
        ...events,
        {
          start,
          end,
          title
        }
      ]))

      // setState is async, outputting the events here will most likely return the old value
      console.log(events);
    }
  };

  return (
    <div>
      <Navigation />
      <Calendar
        selectable
        localizer={localizer}
        events={events}
        popup
        startAccessor="start"
        endAccessor="end"
        style={{ height: 700 }}
        onSelectSlot={handleSelect}
      />
    </div>
  )
};
export default MyCalendar;
Matthew Kwong
  • 2,548
  • 2
  • 11
  • 22
  • React function components have absolutely zero to do with functional programming. `this` is undefined because, unlike classes, you can't have an instance of a function; they are invoked, and return a value. Your answer isn't wrong, but the explanation is. – Drew Reese Jul 08 '21 at 07:31