0

i Want to change this class component in function component:

import React from "react";
import "./styles.css";
import DayPicker, { DateUtils } from "react-day-picker";
import "react-day-picker/lib/style.css";

export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.handleDayClick = this.handleDayClick.bind(this);
    this.state = {
      selectedDays: []
    };
  }

  handleDayClick(day, { selected }) {
    const { selectedDays } = this.state;
    if (selected) {
      const selectedIndex = selectedDays.findIndex((selectedDay) =>
        DateUtils.isSameDay(selectedDay, day)
      );
      selectedDays.splice(selectedIndex, 1);
    } else {
      selectedDays.push(day);
    }
    this.setState({ selectedDays });
  }

  render() {
    return (
      <div>
        {console.log(this.state.selectedDays)}
        <DayPicker
          selectedDays={this.state.selectedDays}
          onDayClick={this.handleDayClick}
        />
      </div>
    );
  }
}

demo: https://codesandbox.io/s/agitated-chaum-0qss8?file=/src/App.js:0-944
I did this:

 const [selectedDays, setSelectedDays] = useState([])

    const handleDayClick = (day, {selected}) => {
        if (selected) {
            const selectedIndex = selectedDays.findIndex(selectedDay =>
                DateUtils.isSameDay(selectedDay, day)
            );
            console.log('test',selectedDays);

            selectedDays.splice(selectedIndex, 1);
        } else {
            // selectedDays.push(day)
            setSelectedDays([...selectedDays,day]);

        }
    }
    console.log(selectedDays);
    return (
        <div className="er">
            <DayPicker
                selectedDays={selectedDays}
                onDayClick={handleDayClick}
            />
        </div>
    );
};

The issue: When i select 1 date the date becomes active, but when i click again on it it does not change back into un-active state? What is the problem and how to solve?

Asking
  • 3,487
  • 11
  • 51
  • 106
  • How does the `day` look like? The problem is in `.splice` I'm nearly sure, but in order to understand how to fix it I'd like to see the day structure. – Konstantin Dec 28 '20 at 14:35
  • @Konstantin, what i want to achieve is next: when i will clik on a date it should be active but when i will click send time the date should change the state to normal. Could you help? – Asking Dec 28 '20 at 14:45
  • Can you please add how `day` looks then? – Konstantin Dec 28 '20 at 14:49
  • @Konstantin, what do you mean? How looks when i click? I has a background that matrk the day as selected. – Asking Dec 28 '20 at 14:57

5 Answers5

0

Here is this working for you.

import React, {useState} from "react";
import "./styles.css";
import DayPicker, { DateUtils } from "react-day-picker";
import "react-day-picker/lib/style.css";

export default App =()=> {
  const [selectedDays, setSelectedDays] = useState([]);

  const handleDayClick=(day, { selected })=> {
    
    if (selected) {
      const selectedIndex = selectedDays.findIndex((selectedDay) =>
        DateUtils.isSameDay(selectedDay, day)
      );
      selectedDays.splice(selectedIndex, 1);
    } else {
      selectedDays.push(day);
    }
    setSelectedDays( selectedDays );
  }

 
    return (
      <div>
        {console.log(this.state.selectedDays)}
        <DayPicker
          selectedDays={selectedDays}
          onDayClick={handleDayClick}
        />
      </div>
    );
  
}
Muhammad Jaan
  • 291
  • 3
  • 10
0

Have updated the answer, earlier i was actually mutating the state, which isnt the best practice.

import React, { useState } from "react";
import "./styles.css";
import DayPicker, { DateUtils } from "react-day-picker";
import "react-day-picker/lib/style.css";

export default function Class1() {
  const [selectedDays, setSelectedDays] = useState([]);
  function handleDayClick(day, { selected }) {
    const selectedDaysNew = [...selectedDays];
    if (selected) {
      const selectedIndex = selectedDaysNew.findIndex((selectedDay) =>
        DateUtils.isSameDay(selectedDay, day)
      );
      selectedDaysNew.splice(selectedIndex, 1);
    } else {
      selectedDaysNew.push(day);
    }
    setSelectedDays(selectedDaysNew);
  }

  return (
    <div>
      {console.log(selectedDays)}
      <DayPicker selectedDays={selectedDays} onDayClick={handleDayClick} />
    </div>
  );
}
amit wadhwani
  • 1,140
  • 1
  • 7
  • 12
0

It's getting a bit hard to talk in the comments, so I'm gonna post an answer.

Does it change anything (it's a question) if you do it like this:

const handleDayClick=(day, { selected })=> {
const currentState = [...selectedDays];

    if (selected) {
      const selectedIndex = currentState.findIndex((selectedDay) =>
        DateUtils.isSameDay(selectedDay, day)
      );
      currentState.splice(selectedIndex, 1);
    } else {
      currentState.push(day);
    }
    setSelectedDays(currentState);
  }
Konstantin
  • 1,390
  • 6
  • 18
0

you should not mutate original state array, create a copy from state array first:

const handleDayClick = (day, {selected}) => {
  setSelectedDays(prevSelected => {
    const selectedDays = [...prevSelected]
    if (selected) {
      const selectedIndex = selectedDays.findIndex(selectedDay =>
          DateUtils.isSameDay(selectedDay, day)
      );
      console.log('test',selectedDays);

      selectedDays.splice(selectedIndex, 1);
      return selectedDays
    } else {
      return [...selectedDays,day]
    }
  })
}
buzatto
  • 9,704
  • 5
  • 24
  • 33
0

Never mutate state directly you are doing some operation directly with muted state variable which may the cause for unappreciated bug.

please refer this links bellow Why Not To Modify React State Directly and stack-overflow these concept apply the same for both class state or useState in components.

i just create a new array before proceeding and it's work fine. codesandbox

import React, { useState } from "react";
import "./styles.css";
import DayPicker, { DateUtils } from "react-day-picker";
import "react-day-picker/lib/style.css";

export default () => {
  const [selectedDays, setSelectedDays] = useState([]);
  const handleDayClick = (day, { selected }) => {
    const selectedDaysTemp = [...selectedDays]; // here is the change creating the new array 
    if (selected) {
      const selectedIndex = selectedDaysTemp.findIndex((selectedDay) =>
        DateUtils.isSameDay(selectedDay, day)
      );
      selectedDaysTemp.splice(selectedIndex, 1);
    } else {
      selectedDaysTemp.push(day);
    }
    setSelectedDays(selectedDaysTemp);
  };
  return (
    <div>
      {console.log(selectedDays)}
      <DayPicker selectedDays={selectedDays} onDayClick={handleDayClick} />
    </div>
  );
}; 
Sunil Kumar
  • 420
  • 4
  • 13