我在react js中创建了一个日历日期范围选择器,我遇到了一个问题,每当我点击日历中的一天,所有的日子都会重新呈现。
下面是我的主要日历组件
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import CalendarDay from './CalendarDay';
export default function Calendar(props) {
const days = [
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21,
22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
];
const [selectedDates, setSelectedDates] = useState({
start: null,
end: null,
});
useEffect(() => {
console.log(selectedDates);
}, [selectedDates]);
const handleDateSelect = useCallback(
(day) => {
if (!selectedDates.start) {
setSelectedDates((prev) => ({ ...prev, start: day }));
} else if (!selectedDates.end) {
setSelectedDates((prev) => ({ ...prev, end: day }));
} else {
setSelectedDates({ start: day, end: null });
}
},
[selectedDates.start, selectedDates.end]
);
return (
<>
<button onClick={() => setSelectedDates({ start: null, end: null })}>
clear dates
</button>
<div>start: {selectedDates.start}</div>
<div>end: {selectedDates.end}</div>
<div className="calendar">
{days.map((day, idx) => {
const key = `${props.year}-${props.month}-${idx + 1}`;
const isSelectedOrInRange = () => {
if (
selectedDates.start === day ||
selectedDates.end === day ||
(day <= selectedDates.end && day >= selectedDates.start)
) {
return true;
}
return false;
};
return (
<CalendarDay
key={key}
day={day}
isSelectedOrInRange={isSelectedOrInRange()}
handleDateSelect={handleDateSelect}
/>
);
})}
</div>
</>
);
}
字符串
这是我的CalendarDay
组件(这是总是重新渲染的)
import React, { memo } from 'react';
function CalendarDay(props) {
const { handleDateSelect, day, isSelectedOrInRange } = props;
console.log(' - rendering: ', day);
return (
<div
className={'day' + (isSelectedOrInRange ? ' selected' : '')}
onClick={() => handleDateSelect(day)}
>
{day}
</div>
);
}
export default memo(CalendarDay);
型
styles.css(在index.js中导入)
* {
box-sizing: border-box;
}
.calendar {
width: 400px;
display: flex;
flex-wrap: wrap;
}
.day {
width: calc(400px / 7);
height: 50px;
border: 1px solid green;
text-align: center;
display: flex;
justify-content: center;
align-items: center;
}
.selected {
color: white;
background: red;
}
型
有没有一种方法可以防止任何calendarDay框重新呈现,除非它被点击或日期在选择之间?
这里有一个stackblitz供您使用
1条答案
按热度按时间xzlaal3s1#
由于您使用的是
React.memo
,因此CalendarDay
仅在其props更改时进行渲染,但您可以在selectedDates.start
或selectedDate.end
更改时更改handleDateSelect
函数。避免这种情况的一种方法是只在
handleDateSelect
函数中使用prev
值,避免为回调声明任何依赖关系:字符串