Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scroll resets to first selected element in a multipleDates calendar when state is updated #239

Open
davidjmstewart opened this issue Dec 1, 2020 · 3 comments

Comments

@davidjmstewart
Copy link

davidjmstewart commented Dec 1, 2020

When using multiple dates functionality, the calendar resets to the zoom to focus on the first selected date on a re-render.

I think most users would expect the scroll to remain unchanged. Is there a way to use the InfiniteCalendar API to avoid this?

See this CodeSandbox

ezgif-3-f09e75df0763

Full code

import React, { useState } from "react";
import "./styles.css";
import InfiniteCalendar, {
  Calendar,
  defaultMultipleDateInterpolation,
  withMultipleDates,
} from 'react-infinite-calendar';
import 'react-infinite-calendar/styles.css'; // only needs to be imported once

export default function App() {

  const [selectedCalendarDates, setSelectedCalendarDates] = useState([]);

  const arrayRemove = (arr, value) => {
    return arr.filter(function (ele) {
      return ele != value;
    });
  }

  // Credit: Mayura Wijewickrama https://stackoverflow.com/questions/45504601/react-infinite-calendar-set-the-date
  const updateSelectedCalendarDates = (date) => {
    var converted =  date.toLocaleString('default', { weekday: 'short' }) 
                  + ' ' + date.toLocaleString('default', { month: 'short' }) 
                  + ' ' + date.getDate() + ' ' +date.getFullYear() + ' 00:00:00';

    if (!selectedCalendarDates.includes(converted)) {
        setSelectedCalendarDates([...selectedCalendarDates, converted]);
    } else {
        var result = arrayRemove(selectedCalendarDates, converted);
        setSelectedCalendarDates(result);
    }
  }

    return (
        <InfiniteCalendar
        Component={withMultipleDates(Calendar)}
        selected={selectedCalendarDates}
        width={'100%'}
        height={600}
        interpolateSelection={defaultMultipleDateInterpolation}
        onSelect={updateSelectedCalendarDates}
        minDate={new Date()} // Minimum selectable date is today
        min={new Date()} // Minimum date the calendar can be scrolled to is today
    />
  );
}

@fteichma
Copy link

This is a problem with the height property,
quick fix: remove the height prop

<InfiniteCalendar
        Component={withMultipleDates(Calendar)}
        selected={selectedCalendarDates}
        width={'100%'}
        interpolateSelection={defaultMultipleDateInterpolation}
        onSelect={updateSelectedCalendarDates}
        minDate={new Date()} // Minimum selectable date is today
        min={new Date()} // Minimum date the calendar can be scrolled to is today
    />

@brooth
Copy link

brooth commented Oct 14, 2021

I fixed it by moving the component declaration out of the building method as follows:

const IntiniteCalendarComponent = withMultipleDates(Calendar);

export default () => {
 ...
  <InfiniteCalendar
              Component={IntiniteCalendarComponent}
              .../>

@ludvigaldrin
Copy link

Did you guys solve this? I tracked it down to the onSelect={updateSelectedCalendarDates}. Since it updates the state it then rerenders the component. I could understand that if you have the state in selected. But I tried with different statets and it still rerenders. Any update or fix?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants