<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Spencer-Brown80</title>
    <description>The latest articles on DEV Community by Spencer-Brown80 (@spencerbrown80).</description>
    <link>https://dev.to/spencerbrown80</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1282915%2F8d2bb6f3-bb23-4fe7-a1d1-24942ab52a0a.jpeg</url>
      <title>DEV Community: Spencer-Brown80</title>
      <link>https://dev.to/spencerbrown80</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/spencerbrown80"/>
    <language>en</language>
    <item>
      <title>React Big Calendar Functionality in a Scheduling Application</title>
      <dc:creator>Spencer-Brown80</dc:creator>
      <pubDate>Fri, 31 May 2024 13:55:29 +0000</pubDate>
      <link>https://dev.to/spencerbrown80/react-big-calendar-functionality-in-a-scheduling-application-2n4g</link>
      <guid>https://dev.to/spencerbrown80/react-big-calendar-functionality-in-a-scheduling-application-2n4g</guid>
      <description>&lt;p&gt;While recently working on a full-stack development project, I got to experience the usefulness of React Big-Calendar.   My aim was to create a scheduling application for a home health nurse that would improve their ability to logistically plan their day.   This involved creating a calendar that would hold and update current events.  The inspiration for the application came from my years working in the home care industry.  I wanted the user to be able to have the functionality of a home care scheduling application while also being easy to use.&lt;/p&gt;

&lt;p&gt;To start using react big-calendar we can install by running this on your client side:&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;&lt;code&gt;npm install react-big-calendar moment @chakra-ui/react&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;p&gt;You will need to initialize your application inside of a page or a component.  I initialized mine in a component called UserCalendar. Below is a reduced version of my code to get started.  You will have many options to tailor the calendar as you build.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React, { useEffect, useState } from "react";
import { Box, Button, useDisclosure, Select, Badge, Stack } from "@chakra-ui/react";
import { Calendar, momentLocalizer, Views } from "react-big-calendar";
import moment from "moment";
import "react-big-calendar/lib/css/react-big-calendar.css";

const localizer = momentLocalizer(moment);
const EVENT_STATUS_COLORS = { 1: "gray", 2: "green", 3: "yellow", 4: "blue", 5: "magenta" };

const UserCalendar = () =&amp;gt; {
  const [events, setEvents] = useState([]);
  const { isOpen, onOpen, onClose } = useDisclosure();

  useEffect(() =&amp;gt; {
    fetch("/api/events")
      .then(response =&amp;gt; response.json())
      .then(data =&amp;gt; setEvents(data.map(event =&amp;gt; ({
        ...event, start: new Date(event.start), end: new Date(event.end)
      }))));
  }, []);

  return (
    &amp;lt;Box&amp;gt;
      &amp;lt;Button onClick={onOpen}&amp;gt;Add Event&amp;lt;/Button&amp;gt;
      &amp;lt;Stack direction="row" mb={4}&amp;gt;
        {Object.entries(EVENT_STATUS_COLORS).map(([status, color]) =&amp;gt; (
          &amp;lt;Badge key={status} colorScheme={color}&amp;gt;{status}&amp;lt;/Badge&amp;gt;
        ))}
      &amp;lt;/Stack&amp;gt;
      &amp;lt;Calendar
        localizer={localizer}
        events={events}
        startAccessor="start"
        endAccessor="end"
        style={{ height: 500 }}
        views={[Views.MONTH, Views.WEEK, Views.DAY, Views.AGENDA]}
        eventPropGetter={event =&amp;gt; ({
          style: { backgroundColor: EVENT_STATUS_COLORS[event.status] }
        })}
      /&amp;gt;
    &amp;lt;/Box&amp;gt;
  );
};

export default UserCalendar;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should now have a calendar rendered on your page that allows you to switch between monthly, weekly, daily and agenda views.   The date picker and buttons labeled Today, Next and Back will be present as part of Big Calendar as well.   However, you need to get something on the calendar.   There is no built in form to add events, however, the calendar will react to selecting a slot in the calendar.   I set mine to open an event form that would handle creating simple events to get started.  Once again, this code is only a parital representation of my current event form.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import React from "react";
import { Formik, Form, Field } from "formik";
import { Box, Button, FormControl, FormLabel, Input, Textarea, Switch } from "@chakra-ui/react";

const EventForm = ({ isOpen, onClose, onSubmit, initialValues }) =&amp;gt; {
  return (
    &amp;lt;Formik
      initialValues={initialValues}
      onSubmit={onSubmit}
    &amp;gt;
      {({ values, setFieldValue }) =&amp;gt; (
        &amp;lt;Form&amp;gt;
          &amp;lt;FormControl&amp;gt;
            &amp;lt;FormLabel&amp;gt;Notes&amp;lt;/FormLabel&amp;gt;
            &amp;lt;Field name="notes" as={Textarea} /&amp;gt;
          &amp;lt;/FormControl&amp;gt;
          &amp;lt;FormControl&amp;gt;
            &amp;lt;FormLabel&amp;gt;Start&amp;lt;/FormLabel&amp;gt;
            &amp;lt;Field name="start" type="datetime-local" as={Input} /&amp;gt;
          &amp;lt;/FormControl&amp;gt;
          &amp;lt;FormControl&amp;gt;
            &amp;lt;FormLabel&amp;gt;End&amp;lt;/FormLabel&amp;gt;
            &amp;lt;Field name="end" type="datetime-local" as={Input} /&amp;gt;
          &amp;lt;/FormControl&amp;gt;
          &amp;lt;FormControl&amp;gt;
            &amp;lt;FormLabel&amp;gt;Recurring&amp;lt;/FormLabel&amp;gt;
            &amp;lt;Field name="is_recurring" type="checkbox" as={Switch} /&amp;gt;
          &amp;lt;/FormControl&amp;gt;
          &amp;lt;Button type="submit"&amp;gt;Save&amp;lt;/Button&amp;gt;
        &amp;lt;/

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This snippet allows the user to enter in a start time and an end time on the event form, which is most of what you will need to get started.   I used Chakra UI to help model the forms and provide modality later on.  I believe it provided a nice result.  Depending on your needs, you can customize your event form to present a lot of information to the user.  My event form included fields for the event_status, event_type, add_address, event_address, start_time, end_time, client_name, recurrence_rule, is_recurring, notes, user_id, client_id and parent_event_id.  Actually, I have more, but there's already enough to write about.  By selecting add address or is recurring, additional fields open up on the event form.  This can get very involved quickly, so make decisions on your backend wisely.   &lt;/p&gt;

&lt;h2&gt;
  
  
  Creating Recurring Events
&lt;/h2&gt;

&lt;p&gt;To create recurring events, you need to understand the recurrence rule.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;DTSTART:20240601T100000Z
RRULE:FREQ=WEEKLY;INTERVAL=2;BYDAY=MO,WE;UNTIL=20241231T235959Z
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Explanation&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;FREQ=WEEKLY: This indicates that the frequency of the recurrence is weekly.&lt;br&gt;
INTERVAL=2: This specifies that the event should occur every 2 weeks.&lt;br&gt;
BYDAY=MO,WE: This indicates that the event should occur on Mondays and Wednesdays.&lt;br&gt;
DTSTART:20240601T100000Z: This specifies the start date and time of the first occurrence, in UTC format (June 1, 2024, at 10:00 UTC).&lt;br&gt;
UNTIL=20241231T235959Z: This specifies the end date and time for the recurrence rule, in UTC format (December 31, 2024, at 23:59 UTC).&lt;br&gt;
With this recurrence rule, the event will repeat every other week on Mondays and Wednesdays from June 1, 2024, until December 31, 2024.&lt;/p&gt;

&lt;p&gt;So in order to create recurring events, I needed to make a function to create the recurrence rule, read/parse so it was viewable and the method of selection on my form.  By the way, my application uses the event date, so I did not need to use a DTSTART, but thought it would be nice to put in this example.   &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Method to Generate Recurrence Rule&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import { RRule, rrulestr } from 'rrule';

const createRRule = (values) =&amp;gt; {
  let rrule = "";
  if (values.is_recurring) {
    if (values.recurrence_option === "EOW") {
      rrule = `FREQ=WEEKLY;INTERVAL=2;BYDAY=${values.recurrence_days.join(",")}`;
    } else if (values.recurrence_option === "Monthly") {
      const byDayValues = values.recurrence_weeks.map(week =&amp;gt;
        values.recurrence_days.map(day =&amp;gt; `${week}${day}`).join(",")
      ).join(",");
      rrule = `FREQ=MONTHLY;BYDAY=${byDayValues}`;
    } else if (values.recurrence_option === "Weekly") {
      rrule = `FREQ=WEEKLY;BYDAY=${values.recurrence_days.join(",")}`;
    }
    if (values.recurrence_end) {
      rrule += `;UNTIL=${values.recurrence_end.replace(/-/g, "")}T235959Z`;
    }
  }
  return rrule;
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Method to Parse Recurrence Rule&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const parseRecurrenceRule = (recurrenceRule, setFieldValue) =&amp;gt; {
    if (!recurrenceRule) return;
    const parts = recurrenceRule.split(";");
    let recurrenceDays = [];
    let recurrenceEnd = "";
    let recurrenceOption = "";
    let recurrenceWeeks = [];

    parts.forEach((part) =&amp;gt; {
      if (part.startsWith("FREQ=")) {
        const freq = part.replace("FREQ=", "");
        if (freq === "WEEKLY") {
          if (part.includes("INTERVAL=2")) {
            recurrenceOption = "EOW";
          } else {
            recurrenceOption = "Weekly";
          }
        } else if (freq === "MONTHLY") {
          recurrenceOption = "Monthly";
        }
      } else if (part.startsWith("BYDAY=")) {
        const days = part.replace("BYDAY=", "").split(",");
        if (recurrenceOption === "Monthly") {
          days.forEach(day =&amp;gt; {
            const week = day[0];
            const dayOfWeek = day.substring(1);
            recurrenceWeeks.push(parseInt(week, 10));
            recurrenceDays.push(dayOfWeek);
          });
        } else {
          recurrenceDays = days;
        }
      } else if (part.startsWith("UNTIL=")) {
        const untilDate = part.replace("UNTIL=", "");
        recurrenceEnd = `${untilDate.substring(0, 4)}-${untilDate.substring(4, 6)}-${untilDate.substring(6, 8)}`;
      }
    });

    setFieldValue("recurrence_days", [...new Set(recurrenceDays)]);
    setFieldValue("recurrence_end", recurrenceEnd);
    setFieldValue("recurrence_option", recurrenceOption);
    setFieldValue("recurrence_weeks", [...new Set(recurrenceWeeks)]);
  };
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Formula to Generate Recurring Events&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const generateRecurringEvents = (event) =&amp;gt; {
  if (!event || !event.start) {
    console.error("Invalid event data passed to generateRecurringEvents:", event);
    return [];
  }

  const maxEndDate = new Date(event.start);
  maxEndDate.setDate(maxEndDate.getDate() + 180); // 180 days from start date
  const rule = rrulestr(event.recurrence_rule, { dtstart: new Date(event.start) });
  const occurrences = rule.between(new Date(event.start), maxEndDate, true); // Generate all occurrences

  const recurringEvents = occurrences.map((occurrence) =&amp;gt; {
    if (occurrence &amp;gt; new Date(event.start)) {
      const end = new Date(occurrence);
      end.setTime(end.getTime() + (new Date(event.end) - new Date(event.start))); // Adjust end time
      return {
        start: occurrence.toISOString(),
        end: end.toISOString(),
        type: event.type,
        status: event.status,
        is_fixed: event.is_fixed,
        priority: event.priority,
        is_recurring: false, // Each generated event is not recurring itself
        recurrence_rule: event.recurrence_rule, // Include the recurrence rule
        notify_client: event.notify_client,
        notes: event.notes,
        is_completed: event.is_completed,
        is_endpoint: event.is_endpoint,
        address: event.address,
        city: event.city,
        state: event.state,
        zip: event.zip,
        user_id: event.user_id,
        user_client_id: event.user_client_id,
        parent_event_id: event.id, // Link to the original event
      };
    }
    return null;
  }).filter(event =&amp;gt; event !== null);

  return recurringEvents;
};
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;By using something similar to this you can easily create recurring events.  I elected to have buttons appear to match the needs of the recurrence rule: days, weeks, options.  By storing all of the data in the RRule, and then using the formula to parse it, I saved having to create extra elements in the events table.   &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Updating a Series of Events&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Updating a series of events involves not only creating events but, a little bit more.   I elected to find all events after the date of the selected event based off the parent_event_id created when the event was initialized.   Store those events.  Create new events.  Delete the stored events.  Why not patch?   I think that if certain modifications were to be made to the recurrence rule, like adding a day to the rule, would mean that a post and a patch would need to be done at the same time.  For the same amount of CRUD actions, I thought this approach was cleaner.   &lt;/p&gt;

&lt;h2&gt;
  
  
  Switching Between My View and Client View
&lt;/h2&gt;

&lt;p&gt;One nice feature I found in Big Calendar was that I could switch views from the user view, to the client view, and only see events tied to a selected client.   I originally thought I was going to have to create a separate component, but the calendar took care of it for me with a little added code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const [view, setView] = useState("my");
const [selectedClient, setSelectedClient] = useState(null);

const toggleView = () =&amp;gt; {
  setView(view === "my" ? "client" : "my");
  setSelectedClient(null); // Reset selected client when switching views
};

const filteredEvents = events.filter(event =&amp;gt; {
  if (view === "my") {
    return event.type !== 3; // Exclude "Client Unavailable" events
  } else if (view === "client") {
    return event.type !== 2 &amp;amp;&amp;amp; event.user_client_id === parseInt(selectedClient);
  }
  return true;
});

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Handling Overdue and Overlapping Events
&lt;/h2&gt;

&lt;p&gt;I was able to assign colors to my events based on their status (pending, confirmed, completed,cancelled), but I wanted the user to see visually events that were conflicted or overdue.  By modifying the UserCalendar we can achieve this.   Here is my method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const eventPropGetter = (event) =&amp;gt; {
  const isOverdue = !event.is_completed &amp;amp;&amp;amp; new Date() &amp;gt; new Date(event.end);
  const overlappingIds = findOverlappingEvents(events);
  const isOverlap = overlappingIds.includes(event.id);
  const backgroundColor = isOverdue ? "red" : (isOverlap ? "orange" : EVENT_STATUS_COLORS[event.status]);
  return { style: { backgroundColor } };
};

const findOverlappingEvents = (events) =&amp;gt; {
  const overlaps = [];
  for (let i = 0; i &amp;lt; events.length; i++) {
    for (let j = i + 1; j &amp;lt; events.length; j++) {
      if (new Date(events[i].end) &amp;gt; new Date(events[j].start) &amp;amp;&amp;amp; new Date(events[i].start) &amp;lt; new Date(events[j].end)) {
        overlaps.push(events[i].id);
        overlaps.push(events[j].id);
      }
    }
  }
  return overlaps;
};

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Practical User Agenda
&lt;/h2&gt;

&lt;p&gt;If you are picky, like me, you may not like the agenda view in Big Calendar.   I only covers a range of dates and the daily view page was great for creating events as a tool, but not what I wanted the user to see.   By creating a User Agenda that listed the events of the day in order, with helpful links to the event, client profile, directions, event type and notes.   The user can view the associated event forms, pick dates and add events.  I set my agenda to fetch the data from events like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const DailyAgenda = ({ userId, selectedDate, onDateChange, onPreviousDay, onNextDay }) =&amp;gt; {
  const [events, setEvents] = useState([]);
  const [clients, setClients] = useState([]);
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [selectedEvent, setSelectedEvent] = useState(null);
  const navigate = useNavigate();

  useEffect(() =&amp;gt; {
    const fetchEvents = async () =&amp;gt; {
      try {
        const response = await fetch(`/api/users/${userId}/events?date=${selectedDate.toISOString().split('T')[0]}`);
        let eventsData = await response.json();
        eventsData = eventsData.filter(event =&amp;gt; event.type !== 3);
        const clientDetails = await Promise.all(eventsData.map(async (event) =&amp;gt; {
          const clientResponse = await fetch(`/api/user_clients/${event.user_client_id}`);
          const clientData = await clientResponse.json();
          return {
            ...event,
            client_address: clientData.address_line_1,
            client_city: clientData.city,
            client_state: clientData.state,
            client_zip: clientData.zip,
          };
        }));
        setEvents(clientDetails);
      } catch (error) {
        console.error('Error fetching events:', error);
      }
    };

    const fetchClients = async () =&amp;gt; {
      try {
        const response = await fetch(`/api/user_clients`);
        const clientsData = await response.json();
        setClients(clientsData);
      } catch (error) {
        console.error('Error fetching clients:', error);
      }
    };

    fetchEvents();
    fetchClients();
  }, [selectedDate, userId]);

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I rendered the agenda incorporating links like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const handleOpenModal = (event) =&amp;gt; {
  setSelectedEvent(event);
  setIsModalOpen(true);
};

const handleCloseModal = () =&amp;gt; {
  setSelectedEvent(null);
  setIsModalOpen(false);
};

return (
  &amp;lt;Box&amp;gt;
    &amp;lt;Flex justifyContent="space-between" alignItems="center" mb={4}&amp;gt;
      &amp;lt;Button colorScheme="blue" onClick={() =&amp;gt; handleOpenModal(null)}&amp;gt;
        Add Event
      &amp;lt;/Button&amp;gt;
      &amp;lt;Text fontSize="2xl" fontWeight="bold"&amp;gt;Daily Agenda&amp;lt;/Text&amp;gt;
      &amp;lt;Flex alignItems="center"&amp;gt;
        &amp;lt;Button onClick={onPreviousDay}&amp;gt;Previous&amp;lt;/Button&amp;gt;
        &amp;lt;DatePicker
          selected={selectedDate}
          onChange={onDateChange}
          dateFormat="yyyy-MM-dd"
          customInput={&amp;lt;Button&amp;gt;{format(selectedDate, 'yyyy-MM-dd')}&amp;lt;/Button&amp;gt;}
        /&amp;gt;
        &amp;lt;Button onClick={onNextDay}&amp;gt;Next&amp;lt;/Button&amp;gt;
      &amp;lt;/Flex&amp;gt;
    &amp;lt;/Flex&amp;gt;
    &amp;lt;Text fontSize="lg" fontWeight="bold" textAlign="center" mb={4}&amp;gt;
      {format(selectedDate, 'EEEE, MMMM d, yyyy')}
    &amp;lt;/Text&amp;gt;
    &amp;lt;Table variant="striped" colorScheme="teal"&amp;gt;
      &amp;lt;Thead&amp;gt;
        &amp;lt;Tr&amp;gt;
          &amp;lt;Th&amp;gt;Time&amp;lt;/Th&amp;gt;
          &amp;lt;Th&amp;gt;Client Name&amp;lt;/Th&amp;gt;
          &amp;lt;Th&amp;gt;Address&amp;lt;/Th&amp;gt;
          &amp;lt;Th&amp;gt;Type&amp;lt;/Th&amp;gt;
          &amp;lt;Th&amp;gt;Notes&amp;lt;/Th&amp;gt;
        &amp;lt;/Tr&amp;gt;
      &amp;lt;/Thead&amp;gt;
      &amp;lt;Tbody&amp;gt;
        {events.map(event =&amp;gt; (
          &amp;lt;Tr key={event.id}&amp;gt;
            &amp;lt;Td&amp;gt;
              &amp;lt;Button variant="link" onClick={() =&amp;gt; handleOpenModal(event)}&amp;gt;
                {`${new Date(event.start).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })} – ${new Date(event.end).toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}`}
              &amp;lt;/Button&amp;gt;
            &amp;lt;/Td&amp;gt;
            &amp;lt;Td&amp;gt;
              &amp;lt;Button variant="link" onClick={() =&amp;gt; navigate(`/usermenu/${userId}/clients/${event.user_client_id}`)}&amp;gt;
                {event.client_name}
              &amp;lt;/Button&amp;gt;
            &amp;lt;/Td&amp;gt;
            &amp;lt;Td&amp;gt;
              &amp;lt;Button
                variant="link"
                onClick={() =&amp;gt; window.open(`https://www.google.com/maps/dir/?api=1&amp;amp;destination=${event.address || `${event.client_address}, ${event.client_city}, ${event.client_state}, ${event.client_zip}`}`, '_blank')}
              &amp;gt;
                {event.address || `${event.client_address}, ${event.client_city}, ${event.client_state}, ${event.client_zip}`}
              &amp;lt;/Button&amp;gt;
            &amp;lt;/Td&amp;gt;
            &amp;lt;Td&amp;gt;{EVENT_TYPE_MAP[event.type]}&amp;lt;/Td&amp;gt;
            &amp;lt;Td&amp;gt;{event.notes.slice(0, 20)}{event.notes.length &amp;gt; 20 &amp;amp;&amp;amp; '...'}&amp;lt;/Td&amp;gt;
          &amp;lt;/Tr&amp;gt;
        ))}
      &amp;lt;/Tbody&amp;gt;
    &amp;lt;/Table&amp;gt;
    &amp;lt;Modal isOpen={isModalOpen} onClose={handleCloseModal}&amp;gt;
      &amp;lt;ModalOverlay /&amp;gt;
      &amp;lt;ModalContent&amp;gt;
        &amp;lt;ModalHeader&amp;gt;{selectedEvent ? 'Edit Event' : 'Add Event'}&amp;lt;/ModalHeader&amp;gt;
        &amp;lt;ModalCloseButton /&amp;gt;
        &amp;lt;ModalBody&amp;gt;
          &amp;lt;EventForm event={selectedEvent} clients={clients} onClose={handleCloseModal} /&amp;gt;
        &amp;lt;/ModalBody&amp;gt;
      &amp;lt;/ModalContent&amp;gt;
    &amp;lt;/Modal&amp;gt;
  &amp;lt;/Box&amp;gt;
);
};

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With a little bit a coding you can create an easy to use agenda for your users.  &lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;Creating a user friendly application in Big Calendar is not only possible, but with enough tailoring, you can make an excellent professional scheduling application that will work similarly to one's companies pay lots of money for their employees to use.   Even better, React Big Calendar is free.   So give it a try.   Hope you enjoyed this article.   If you have any questions or comments, let me know.   Take Care.   &lt;/p&gt;

</description>
    </item>
    <item>
      <title>Basic principles of Formik</title>
      <dc:creator>Spencer-Brown80</dc:creator>
      <pubDate>Mon, 13 May 2024 13:01:20 +0000</pubDate>
      <link>https://dev.to/spencerbrown80/basic-principles-of-formik-2o6d</link>
      <guid>https://dev.to/spencerbrown80/basic-principles-of-formik-2o6d</guid>
      <description>&lt;p&gt;Forms are an integral part of web applications, often serving as a bridge for user interaction and data submission. However, managing forms in React can become cumbersome, especially as the complexity of your forms grows. This is where Formik comes to the rescue. Formik is a library for building forms in React that aims to simplify the process of form management by handling form state, validation, and submission seamlessly. In this comprehensive guide, we will delve into the world of Formik, exploring its features, benefits, and how to effectively utilize it in your React projects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Introduction to Formik&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Formik, created by Jared Palmer, has gained widespread adoption in the React community due to its simplicity and powerful features. At its core, Formik provides a set of React components and hooks that streamline the process of building and managing forms. It abstracts away the complexities of form handling, allowing developers to focus on creating robust user interfaces without worrying about the intricacies of form state management.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Key Features of Formik&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Declarative Approach: Formik adopts a declarative approach to form management, allowing developers to define forms using JSX syntax. This makes it intuitive and easy to understand, especially for developers familiar with React.&lt;/p&gt;

&lt;p&gt;&lt;u&gt;Form State Management:&lt;/u&gt; Formik efficiently manages the state of form components, including field values, touched and visited state, and form submission status. It handles the synchronization of form values with React state, ensuring a seamless user experience.&lt;/p&gt;

&lt;p&gt;&lt;u&gt;Form Validation&lt;/u&gt;: Validating user input is crucial for ensuring data integrity and preventing errors. Formik simplifies the process of form validation by providing built-in validation utilities and error handling mechanisms. Developers can define validation schemas using Yup, a powerful schema validation library, or custom validation functions.&lt;/p&gt;

&lt;p&gt;&lt;u&gt;Form Submission Handling&lt;/u&gt;: Formik simplifies the process of handling form submissions, including asynchronous operations such as data fetching or API calls. It provides hooks and utilities for submitting form data, tracking submission status, and handling errors.&lt;/p&gt;

&lt;p&gt;&lt;u&gt;Field-Level Validation&lt;/u&gt;: In addition to form-level validation, Formik supports field-level validation, allowing developers to define validation rules for individual form fields. This granular control over validation enhances the user experience by providing real-time feedback to users as they interact with the form.&lt;/p&gt;

&lt;p&gt;&lt;u&gt;Integration with React Ecosystem&lt;/u&gt;: Formik seamlessly integrates with other libraries and frameworks in the React ecosystem, such as React Router and Material-UI. This interoperability allows developers to leverage existing tools and components while building forms with Formik.&lt;/p&gt;

&lt;p&gt;Below is a simple login form using Formik to illustrate its usage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;
import React from 'react';
import { Formik, Form, Field, ErrorMessage } from 'formik';

const LoginForm = () =&amp;gt; (
  &amp;lt;Formik
    initialValues={{ email: '', password: '' }}
    validate={(values) =&amp;gt; {
      const errors = {};
      if (!values.email) {
        errors.email = 'Email is required';
      }
      if (!values.password) {
        errors.password = 'Password is required';
      }
      return errors;
    }}
    onSubmit={(values, { setSubmitting }) =&amp;gt; {
      setTimeout(() =&amp;gt; {
        alert(JSON.stringify(values, null, 2));
        setSubmitting(false);
      }, 400);
    }}
  &amp;gt;
    {({ isSubmitting }) =&amp;gt; (
      &amp;lt;Form&amp;gt;
        &amp;lt;Field type="email" name="email" /&amp;gt;
        &amp;lt;ErrorMessage name="email" component="div" /&amp;gt;

        &amp;lt;Field type="password" name="password" /&amp;gt;
        &amp;lt;ErrorMessage name="password" component="div" /&amp;gt;

        &amp;lt;button type="submit" disabled={isSubmitting}&amp;gt;
          Submit
        &amp;lt;/button&amp;gt;
      &amp;lt;/Form&amp;gt;
    )}
  &amp;lt;/Formik&amp;gt;
);

export default LoginForm;


&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this example, we define a LoginForm component using Formik's Formik, Form, Field, and ErrorMessage components. We specify initial form values, validation logic, and submission handling using the initialValues, validate, and onSubmit props, respectively.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Resources and Further Learning&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;u&gt;Official Documentation&lt;/u&gt;: The official documentation provides comprehensive guides, API references, and examples to help you master Formik. &lt;br&gt;
(URL: &lt;a href="https://formik.org/docs/overview"&gt;https://formik.org/docs/overview&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;u&gt;Formik GitHub Repository&lt;/u&gt;: You can explore the Formik GitHub repository to view the source code, file issues, and contribute to the project. &lt;br&gt;
(URL: &lt;a href="https://github.com/formium/formik"&gt;https://github.com/formium/formik&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;u&gt;Formik Examples&lt;/u&gt;: The Formik GitHub repository includes a collection of examples demonstrating various use cases and integrations with other libraries. &lt;br&gt;
(URL: &lt;a href="https://github.com/formium/formik/tree/master/examples"&gt;https://github.com/formium/formik/tree/master/examples&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;u&gt;Formik vs. React Hook Form&lt;/u&gt;: If you're evaluating different form management libraries, you might find this comparison between Formik and React Hook Form insightful. (URL: &lt;a href="https://www.codementor.io/@innocentmakaba/react-form-handling-formik-vs-react-hook-form-voil3mmhc"&gt;https://www.codementor.io/@innocentmakaba/react-form-handling-formik-vs-react-hook-form-voil3mmhc&lt;/a&gt;)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;em&gt;Conclusion&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Formik simplifies form management in React applications, providing a powerful yet intuitive solution for handling form state, validation, and submission. By leveraging Formik's declarative API and built-in utilities, developers can create robust and user-friendly forms with ease. Whether you're building simple login forms or complex multi-step wizards, Formik empowers you to focus on crafting delightful user experiences without getting bogged down by form handling intricacies. &lt;/p&gt;

</description>
    </item>
    <item>
      <title>Intro to Python libraries</title>
      <dc:creator>Spencer-Brown80</dc:creator>
      <pubDate>Thu, 18 Apr 2024 16:18:02 +0000</pubDate>
      <link>https://dev.to/spencerbrown80/intro-to-python-libraries-1c12</link>
      <guid>https://dev.to/spencerbrown80/intro-to-python-libraries-1c12</guid>
      <description>&lt;h2&gt;
  
  
  &lt;strong&gt;Introduction:&lt;/strong&gt;
&lt;/h2&gt;

&lt;p&gt;Python has become very popular, thanks in part to its extensive library ecosystem that caters to a wide range of needs. Among these libraries, three stand out for their versatility and utility in creating functional applications with a good user experience: inquirer, matplotlib, and tabulate. In this beginner's guide, we'll explore how these libraries can be used to build practical applications that not only perform tasks efficiently but also provide a seamless user interface.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Getting Started with Inquirer:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Inquirer is a Python library that simplifies the process of creating interactive command-line interfaces (CLIs) by providing a set of common interface elements such as prompts, checkboxes, and text inputs. Its intuitive API makes it easy to build applications that engage users and collect input effectively.&lt;/p&gt;

&lt;p&gt;Imagine you're tasked with building a quiz application similar to those used in schools or companies for assessments. With inquirer, you can quickly implement the necessary prompts to gather responses from users in a structured manner. Let's take a look at a simple example:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj5in1xd9tpgms0xvzhd2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fj5in1xd9tpgms0xvzhd2.png" alt="Image description" width="800" height="466"&gt;&lt;/a&gt;  &lt;/p&gt;

&lt;p&gt;In this code snippet, we are displaying 10 random questions from our table of quiz questions and then shuffling the answers.  By simply using inquirer.list_input() and passing in the choices we create the ability for the user to simply arrow up and down the choices to select their answer.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnsf2v7efpnq0zup1sube.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnsf2v7efpnq0zup1sube.png" alt="Image description" width="800" height="260"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is only one example from our application.  We incorporated into many areas of our CLI.  Inquirer offers a variety of prompt types and many more customization options to tailor the user experience to your application's needs. You can explore the full range of features in the &lt;a href="https://github.com/magmax/python-inquirer"&gt;official documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Visualizing Data with Matplotlib:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Matplotlib is a powerful library for creating static, animated, and interactive visualizations in Python. It's widely used in scientific computing, data analysis, and machine learning for its flexibility and ease of use. One of its key features is its ability to generate high-quality plots with just a few lines of code.&lt;/p&gt;

&lt;p&gt;Suppose you're working on a project to analyze student grades and visualize their performance. Matplotlib can help you create informative plots that highlight trends and patterns in the data. Let's consider a scenario where you want to plot student grades on a scatter plot and visualize the class average:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzp3vi2aw2ymnlfcerq02.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzp3vi2aw2ymnlfcerq02.png" alt="Image description" width="800" height="637"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this code snippet, we use Matplotlib to create a scatter plot of student grades, with each student represented by a point on the graph. The user's score is another scatterplot, with only one value, which allows us to change it's color.  We then add a dashed red line to indicate the class average. By visualizing the data in this way, we can quickly identify outliers and assess overall performance.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx1cjsd8u49aoxl0itdng.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fx1cjsd8u49aoxl0itdng.png" alt="Image description" width="800" height="533"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Matplotlib offers a wide range of plotting functions and customization options to suit various needs. You can explore the full capabilities of Matplotlib in the &lt;a href="https://matplotlib.org/"&gt;official documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Generating Tables with Tabulate:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Tabulate is a lightweight Python library for formatting tabular data in a visually appealing manner. It provides a simple interface for generating tables in CLI applications, making it ideal for displaying structured information to users.&lt;/p&gt;

&lt;p&gt;Continuing with our quiz application example, let's say you want to present users with a summary of their quiz results in a neat tabular format. Tabulate makes it easy to achieve this with minimal effort:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8b8ieul2krwvmltq5upp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F8b8ieul2krwvmltq5upp.png" alt="Image description" width="800" height="323"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;In this code snippet, we use Tabulate to create a formatted table of quiz results, including columns for the quiz name, score, and the date the quiz was taken. The tablefmt='fancy_grid' option adds a visually appealing grid layout to the table, enhancing readability.  &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkqeqyhjd4stk36wf5t9d.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fkqeqyhjd4stk36wf5t9d.png" alt="Image description" width="800" height="916"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Tabulate offers various table formatting options and styles to suit different preferences. You can explore the full range of features in the &lt;a href="https://pypi.org/project/tabulate/"&gt;official documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Exploring Further Possibilities:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;The examples provided in this guide only scratch the surface of what can be achieved with inquirer, matplotlib, and tabulate. As you continue your journey in Python development, there's a vast world of possibilities waiting to be explored within these libraries.&lt;/p&gt;

&lt;p&gt;With inquirer, you can dive deeper into its capabilities by incorporating more complex prompts and validation mechanisms. For instance, you can implement conditional logic to dynamically adjust the questions based on previous user responses. Additionally, you can explore advanced styling options to create visually appealing interfaces that align with your application's design aesthetic. Inquirer's extensive documentation provides valuable insights and examples to guide you through these advanced features.&lt;/p&gt;

&lt;p&gt;Matplotlib offers an extensive array of plotting functions and customization options beyond what we've covered in this guide. Experiment with different plot types such as histograms, bar charts, and heatmaps to visualize your data from various perspectives. Delve into the realm of 3D plotting or interactive visualizations using Matplotlib's interactive mode or integration with other libraries like PyQt or Tkinter. By exploring the full spectrum of Matplotlib's capabilities, you can create visually stunning visualizations that effectively communicate insights from your data.&lt;/p&gt;

&lt;p&gt;Tabulate provides a solid foundation for generating tables in CLI applications, but there's much more you can do to enhance the presentation and functionality of your tables. Explore advanced formatting techniques such as multi-level headers, custom alignments, and styling options to tailor the appearance of your tables to your specific requirements. You can also integrate tabulate with other libraries or frameworks to enhance interactivity, such as incorporating clickable table cells or enabling sorting and filtering capabilities. The possibilities for customization are virtually limitless, allowing you to create polished and professional-looking tables that elevate the user experience of your CLI applications.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Conclusion:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In this beginner's guide, we've explored how to create functional applications with Python libraries such as inquirer, matplotlib, and tabulate. These libraries offer powerful tools for building interactive command-line interfaces, visualizing data, and formatting tabular information.&lt;/p&gt;

&lt;p&gt;As you continue to explore these libraries and integrate them into your projects, remember to refer to the official documentation and seek out additional resources for further learning. With practice and experimentation, you'll be well on your way to mastering the art of Python development.&lt;/p&gt;

&lt;p&gt;Happy coding!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Exploring Advanced Tools in React Development</title>
      <dc:creator>Spencer-Brown80</dc:creator>
      <pubDate>Sat, 30 Mar 2024 14:44:36 +0000</pubDate>
      <link>https://dev.to/spencerbrown80/exploring-advanced-tools-in-react-development-3113</link>
      <guid>https://dev.to/spencerbrown80/exploring-advanced-tools-in-react-development-3113</guid>
      <description>&lt;p&gt;As you delve deeper into React development, mastering advanced tools becomes paramount for building complex and scalable applications. In this blog post, we'll delve into four advanced tools in React, offering detailed descriptions and relevant resources to enhance your understanding and proficiency. Additionally, we'll explore avenues for staying up-to-date with emerging trends and changes in the React ecosystem.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advanced Tools
&lt;/h2&gt;

&lt;h4&gt;
  
  
  &lt;u&gt;&lt;strong&gt;Hooks&lt;/strong&gt;&lt;/u&gt;
&lt;/h4&gt;

&lt;p&gt;Introduced in React 16.8, Hooks revolutionized how stateful logic is encapsulated and reused in React functional components. Before Hooks, stateful logic was typically confined to class components, leading to more complex code and potential reuse issues. With Hooks, developers can leverage state, context, and other React features within functional components, eliminating the need for class components in many cases.&lt;/p&gt;

&lt;p&gt;Hooks provide a more functional approach to managing component logic, allowing developers to separate concerns and compose custom hooks for sharing logic across components. Key hooks include &lt;a href="https://reactjs.org/docs/hooks-state.html"&gt;useState&lt;/a&gt; for managing component state, &lt;a href="https://reactjs.org/docs/hooks-effect.html"&gt;useEffect&lt;/a&gt; for handling side effects, &lt;a href="https://reactjs.org/docs/hooks-reference.html#usecontext"&gt;useContext&lt;/a&gt; for accessing context within functional components, and many more.&lt;/p&gt;

&lt;p&gt;Explore React Hooks on &lt;a href="https://reactjs.org/docs/hooks-intro.html"&gt;React's official documentation&lt;/a&gt; to learn how to leverage Hooks to streamline your React code and build more maintainable applications.&lt;/p&gt;

&lt;h4&gt;
  
  
  Hook Libraries
&lt;/h4&gt;

&lt;p&gt;While React provides a robust set of built-in hooks, several libraries extend React's functionality with additional hooks tailored for specific use cases. Here are some notable hook libraries you can explore:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://swr.vercel.app/"&gt;useSWR&lt;/a&gt;&lt;/strong&gt;: A React hook for data fetching with support for caching, revalidation, and error handling.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://react-query.tanstack.com/"&gt;react-query&lt;/a&gt;&lt;/strong&gt;: A React hook library for fetching, caching, synchronizing, and updating server state in your React applications.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://github.com/streamich/react-use"&gt;react-use&lt;/a&gt;&lt;/strong&gt;: A collection of essential React hooks for common use cases, including form handling, media queries, and more.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://react-hook-form.com/"&gt;react-hook-form&lt;/a&gt;&lt;/strong&gt;: A powerful form validation library with support for complex validation rules, custom hooks, and seamless integration with React.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.npmjs.com/package/use-debounce"&gt;use-debounce&lt;/a&gt;&lt;/strong&gt;: A React hook for debouncing state updates, commonly used for handling input changes with a delay.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These libraries offer convenient solutions for common challenges in React development, allowing you to enhance productivity and build robust applications more efficiently.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;u&gt;&lt;strong&gt;Context&lt;/strong&gt;&lt;/u&gt;
&lt;/h4&gt;

&lt;p&gt;Context provides a mechanism for passing data through the component tree without having to pass props down manually at every level. While props are ideal for passing data down the component tree, they can become cumbersome for deeply nested components or when passing data that's needed by many components. Context addresses this issue by allowing you to create a global data store that can be accessed by any component within the tree.&lt;/p&gt;

&lt;p&gt;Context is particularly useful for managing global settings, user authentication, or theme preferences that need to be accessed by multiple components at different levels of the component hierarchy. By using Context, you can avoid prop drilling and make your code more concise and maintainable.&lt;/p&gt;

&lt;p&gt;Learn how to use Context in React on &lt;a href="https://reactjs.org/docs/context.html"&gt;React's official documentation&lt;/a&gt; and discover how it can simplify state management in your applications.&lt;/p&gt;

&lt;h4&gt;
  
  
  Context Libraries
&lt;/h4&gt;

&lt;p&gt;In addition to basic context usage, several libraries offer templates and utilities to streamline the implementation of context-based state management. Here are a few notable ones:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://www.npmjs.com/package/use-context-selector"&gt;use-context-selector&lt;/a&gt;&lt;/strong&gt;: A lightweight library that allows you to use selectors with React Context, enabling more granular updates and performance optimizations.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://recoiljs.org/"&gt;recoil&lt;/a&gt;&lt;/strong&gt;: A state management library for React applications that leverages React Context under the hood. It provides a simple and efficient way to manage global state with minimal boilerplate.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;&lt;a href="https://redux.js.org/"&gt;redux&lt;/a&gt;&lt;/strong&gt;: Although primarily known for its global state management capabilities, Redux can also be used in conjunction with React's Context API to manage application state.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;These libraries extend the functionality of React's Context API, offering additional features and optimizations for managing global state in your React applications.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;u&gt;&lt;strong&gt;Vite&lt;/strong&gt;&lt;/u&gt;
&lt;/h4&gt;

&lt;p&gt;&lt;a href="https://vitejs.dev/"&gt;Vite&lt;/a&gt; is a blazing fast build tool that significantly improves the development experience for React applications. It leverages modern browser features such as native ES module imports to provide near-instantaneous development server startup and rapid hot module replacement (HMR) updates. This makes the development process incredibly smooth and efficient, especially for large-scale projects.&lt;/p&gt;

&lt;h4&gt;
  
  
  Key Features and Usefulness
&lt;/h4&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Instant Server Start&lt;/strong&gt;: The development server starts almost instantly, eliminating the slow startup times typically associated with traditional bundlers.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lightning-Fast HMR&lt;/strong&gt;: Vite offers rapid hot module replacement (HMR) updates, ensuring that changes made to React components or other modules are reflected in the browser almost instantly without full page reloads.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Optimized Production Builds&lt;/strong&gt;: Vite optimizes production builds by leveraging modern build tools such as Rollup, resulting in smaller bundle sizes and faster loading times for end-users.&lt;/li&gt;
&lt;/ul&gt;

&lt;h4&gt;
  
  
  Integration with VS Code
&lt;/h4&gt;

&lt;p&gt;Vite integrates seamlessly with Visual Studio Code (VS Code), one of the most popular code editors among React developers. The Vite plugin for VS Code provides several features to enhance the development experience:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Intelligent Auto-Completion&lt;/strong&gt;: Enhanced auto-completion capabilities streamline the coding process and reduce errors.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Built-in Dev Server Integration&lt;/strong&gt;: VS Code integrates with Vite's built-in development server, allowing developers to launch and manage their development environment directly from the editor.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Debugging Support&lt;/strong&gt;: Vite's VS Code plugin offers comprehensive debugging support for React applications, facilitating faster bug identification and resolution during development.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By harnessing the power of Vite and its seamless integration with VS Code, React developers can build modern, performant applications more efficiently than ever before.&lt;/p&gt;

&lt;h4&gt;
  
  
  &lt;u&gt;&lt;strong&gt;Staying Up-to-Date&lt;/strong&gt;&lt;/u&gt;
&lt;/h4&gt;

&lt;p&gt;Staying abreast of emerging trends and changes in the React ecosystem is vital for any React developer. Here are some resources and strategies to help you stay up-to-date:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Blogs and Websites&lt;/strong&gt;: &lt;a href="https://reactjs.org/blog/"&gt;React Official Blog&lt;/a&gt;, &lt;a href="https://medium.com/topic/react"&gt;Medium React Topics&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Newsletters&lt;/strong&gt;: &lt;a href="https://react.statuscode.com/"&gt;Subscribe to React Status&lt;/a&gt;, &lt;a href="https://javascriptweekly.com/"&gt;Subscribe to JavaScript Weekly&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Social Media&lt;/strong&gt;: &lt;a href="https://twitter.com/reactjs"&gt;React on Twitter&lt;/a&gt;, &lt;a href="https://www.reddit.com/r/reactjs/"&gt;r/reactjs&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Conferences and Meetups&lt;/strong&gt;: &lt;a href="https://reactjs.org/community/conferences.html"&gt;React Conferences&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By leveraging these resources and actively participating in the React community, you can stay informed about emerging trends, updates, and best practices in React development. Continuously learning and adapting to changes will help you stay ahead in your React journey. Happy coding!&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Some interesting things I learned about Chrome and image titles</title>
      <dc:creator>Spencer-Brown80</dc:creator>
      <pubDate>Thu, 07 Mar 2024 21:09:16 +0000</pubDate>
      <link>https://dev.to/spencerbrown80/some-interesting-things-i-learned-about-chrome-and-image-titles-4b7n</link>
      <guid>https://dev.to/spencerbrown80/some-interesting-things-i-learned-about-chrome-and-image-titles-4b7n</guid>
      <description>&lt;p&gt;While working on a recent project, I noticed that some of the images on my page responded differently.   Some images, when hovered over, would produce a floating text box next to the cursor, while others would not.    Being rather new to programming, I was also confused as to how the text was appearing in the first place.    We hadn’t added that in yet, had we? &lt;/p&gt;

&lt;p&gt;After looking at the Javascript code, it became apparent that Chrome was reading the value of ‘img.title’ that I gave when rendering, and displayed that information whenever the mouse hovered over the image.   Initially, my code to render the image looked like this:    &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7wcnv3yh24n9cmwynz57.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F7wcnv3yh24n9cmwynz57.png" alt="startercode" width="800" height="212"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I searched through my project code but there were no event-listeners for ‘onmouseover’ in my .js files.   The other rendered images that did not have a text display also did not have a ‘ .title’ value declared.  Once I dug a little more, I found that Google calls these ‘tab hover cards’, and they are the default setting for the Chrome browser.   You are able to toggle them at ‘chrome://flags/’.   Understanding the how and why of these ‘cards’ appearing in the first place got me thinking.   &lt;/p&gt;

&lt;p&gt;I decided to see if I could expand upon this functionality for use in my project at the time.   The page our team created pulls random images from different APIs, and displays them whenever the page is loaded.   However, I wanted to include more information than just the artist’s name(artistDisplayName).    &lt;/p&gt;

&lt;p&gt;What if I load all of the information I want to display into the ‘img.title’ value?   Here is a look at how that code started:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwr1bwja4o97x6oeo3i36.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwr1bwja4o97x6oeo3i36.png" alt="code2" width="800" height="150"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This worked!   I was able to display all the image info content that I wanted.   I just had to ensure I referenced each image’s values correctly.   By concatenating the value of ‘img.title’ as a string with these values it was easy to list them in order.    However, the way in which they were displayed left much to be desired.   You are also left with little to no options on formatting the text-box as the ‘onmouseover’ script is running automatically through Chrome.    You are left with a few ways to change the appearance of the content displayed, however.   &lt;/p&gt;

&lt;p&gt;Since this information works being displayed as a string, I decided to incorporate headers for each of my values.   That step was pretty easy and looked like this code below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqrwk188jf602xl6gk850.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqrwk188jf602xl6gk850.png" alt="code3" width="800" height="116"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This formatting worked better.   It also became apparent that the text-box displaying the content has width parameters that will change depending on the amount of information that is passed onto them.    Some of the images from other APIs would return over 100 word descriptions as a displayed value.    One of the nice things that Chrome does with the text-box is that it will decide its own max-width and then automatically wrap the text.    So there is no need to create breaks in the content unless that is preferred.   &lt;/p&gt;

&lt;p&gt;In my case, I did want to create some breaks to start each content value on a separate line.  This was accomplished by adding ‘\n’ between each value.   In Javascript, ‘\n’ stands for newline characters and will work in a string.   This is what the finished code for displaying the image content looked like: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcvye70iq0385l5yaz3ou.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcvye70iq0385l5yaz3ou.png" alt="finishedcode" width="800" height="109"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Please note that it’s written ‘\n’ and not ‘/n’.   In other words, don’t be like me, and completely take yourself off course over an improper slash.   &lt;/p&gt;

&lt;p&gt;If you would like some more info on this topic, you can check out this link: &lt;br&gt;
        &lt;a href="https://support.google.com/chrome/thread/214352441?hl=en&amp;amp;sjid=10184452963716446879-NA"&gt;https://support.google.com/chrome/thread/214352441?hl=en&amp;amp;sjid=10184452963716446879-NA&lt;/a&gt;&lt;br&gt;
It gives some facts on this Google Chrome feature.   So if you are looking to display some more information about your images, or are looking to make it disappear, know that you simply need to manipulate the ‘ .title’ value on that image.   &lt;/p&gt;

&lt;p&gt;This functionality may not work in all browsers, or may require saving the value / values under a different attribute.   Please consider this if your desire is to have your site user experience consistent.    While this method worked well for my project, as my purpose was to simply display images and image info from a server response, it may not work as well for everyone.   If your goal is to optimize your SEO, and you would like your images to show up as relevant search results, tweaking the value of the ‘ .title’ attribute can have a positive or a negative effect.&lt;/p&gt;

&lt;p&gt;I hope this article is helpful to someone out there just starting out in html and css.             &lt;/p&gt;

</description>
    </item>
  </channel>
</rss>
