indexOf() 没有按预期工作,函数不断添加重复项 - React

indexOf() not working as expected, function keeps adding duplicates - React

const [dates, setDates] = useState([]);

const handleClick = (day) => {
  let newArray = [...dates];
  let indexItem = newArray.indexOf(day);
  indexItem === -1 ? newArray.push(day) : newArray.splice(indexItem, 1);
  setDates(newArray);
};

useEffect(() => {
  console.log(dates);
}, [dates]);

return(
  <DayPicker selectedDays={dates} onDayClick={handleClick} />
)

是否可以更新我的代码,使状态只包含单击一次并在单击两次时删除的日期?

能够切换状态中的日期真是太棒了。

我的函数仅在元素添加 2 次后删除该元素,因此无法从数组中删除重复项。

handleClick 中的 day 参数 returns 值作为字符串,如:

Fri Mar 05 2021 12:00:00 GMT+0100 (Central European Standard Time)

当我 console.log() 在浏览器中约会时,它是这样的:

0: Wed Mar 03 2021 12:00:00 GMT+0100 (Central European Standard Time) {}
1: Wed Mar 10 2021 12:00:00 GMT+0100 (Central European Standard Time) {}
2: Wed Mar 17 2021 12:00:00 GMT+0100 (Central European Standard Time) {}
3: Wed Mar 03 2021 12:00:00 GMT+0100 (Central European Standard Time) {}
4: Wed Mar 10 2021 12:00:00 GMT+0100 (Central European Standard Time) {}
5: Wed Mar 17 2021 12:00:00 GMT+0100 (Central European Standard Time) {}

你可以看到重复的,如果我再次点击相同的日子,结果会是

0: Wed Mar 03 2021 12:00:00 GMT+0100 (Central European Standard Time) {}
1: Wed Mar 10 2021 12:00:00 GMT+0100 (Central European Standard Time) {}
2: Wed Mar 17 2021 12:00:00 GMT+0100 (Central European Standard Time) {}

而不是

[]

提前致谢!

问题是库传递给点击处理程序的参数是一个日期,而不是一个字符串,所以 indexOf 不起作用 - 不同的对象不是 === 彼此,即使它们包含相同的值。因此,找到的索引始终为 -1,并且将重复的对象添加到状态。

我会制作一个 timestamps(数字)数组,以便可以轻松检测到重复项:

const [timestamps, setTimestamps] = React.useState([]);

const handleClick = (clickedDate) => {
    const clickedTimestamp = clickedDate.getTime();
    const index = timestamps.indexOf(clickedTimestamp);
    if (index === -1) {
        setTimestamps([...timestamps, clickedTimestamp]);
    } else {
        setTimestamps(
            timestamps.filter((_, i) => i !== index)
        );
    }
};
<DayPicker
    selectedDays={timestamps.map(t => new Date(t))}
    onDayClick={handleClick}
/>

我认为更合适的实现方式是将所选日期转换为时间戳格式,然后将其与状态进行比较。

const [dates, setDates] = useState([]);

  const handleClick = (day) => {
    let currentDay = new Date(day).getTime();
    let newArray = [...dates];
    let indexItem = newArray.indexOf(currentDay);

    indexItem === -1 ? newArray.push(currentDay) : newArray.splice(indexItem, 1);
    setDates(newArray);
  };

  useEffect(() => {
    console.log(dates);
  }, [dates]);

  const selectedDates = dates && dates.map((date) => new Date(date));

  return <DayPicker selectedDays={selectedDates} onDayClick={handleClick} />;