indexOf()没有按预期工作,函数不断添加重复- 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参数以字符串形式返回值,如:

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,重复的对象被添加到状态。

我将制作一个时间戳(数字)数组,这样可以很容易地检测到重复:

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} />;

最新更新