РЕДАКТИРОВАТЬ: обрабатывая это таким образом, вы также можете изменить общее количество дней в месяце и т. Д. Без необходимости жестко кодировать его до 31. Просто пример того, как этот дизайнпозволяет вам быть гибким.
Я лично не понимаю, почему вы передаете setDate
дочернему компоненту ... Я не вижу смысла в этом или что вы выигрываете от этого..
По моему мнению, проблема связана с тем, как вы обрабатываете свой дизайн.
Каждый раз, когда что-то меняется, const year
, const day
, const month
все запускается снова .. этогде вы должны использовать state
. Просто передайте date
в качестве реквизита, затем обработайте все изменения этой даты локально для компонента DatePicker
..., позволяя ребенку связаться с родителем и изменитьэто состояние мне кажется странным.
Примерно так я и поступил бы - это намного чище.
const { useState, useEffect } = React;
const { render } = ReactDOM;
const CalendarDatePicker = ({date, onDateChange}) => {
const [year, setYear] = useState();
const [month, setMonth] = useState();
const [day, setDay] = useState();
const [daysInMonth, setDaysInMonth] = useState();
useEffect(() => {
setYear(date.getFullYear());
setMonth(date.getMonth() + 1);
setDay(date.getDate());
}, [date])
useEffect(() => {
let dim = getDaysInMonth(month, year);
setDaysInMonth(dim);
}, [month, year]);
const handleYearChange = event => {
let nd = new Date(event.target.value, month, day);
setYear(nd.getFullYear());
onDateChange(nd);
}
const handleMonthChange = event => {
let nd = new Date(year, event.target.value - 1, day)
setMonth(nd.getMonth() + 1);
onDateChange(nd);
}
const handleDayChange = event => {
let nd = new Date(year, month, event.target.value);
setDay(nd.getDate());
onDateChange(nd);
}
function getDaysInMonth(month, year) {
return new Date(year, month, 0).getDate();
}
return (
<div>
<div className="form-group">
<label htmlFor="display-year">Year</label>
<input
type="number"
id="display-year"
name="display-year"
className="form-control form-control-sm"
min="1"
value={year}
onChange={handleYearChange} />
</div>
<div className="form-group">
<label htmlFor="display-month">Month</label>
<input
type="number"
id="display-month"
name="display-month"
className="form-control form-control-sm"
min="1"
max="12"
value={month}
onChange={handleMonthChange} />
</div>
<div className="form-group">
<label htmlFor="display-day">Day</label>
<input
type="number"
id="display-day"
name="display-day"
className="form-control form-control-sm"
min="1"
max={daysInMonth}
value={day}
onChange={handleDayChange} />
</div>
</div>
);
}
const Calendar = props => {
const handleDateChange = event => {
console.log('You can change the `Calendar` during this event when the date changes...', event);
}
return (
<div className="bg-light border border-dark rounded p-1">
<CalendarDatePicker date={props.date} onDateChange={handleDateChange} />
</div>
);
}
render(<Calendar date={new Date(Date.now())} />, document.body);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.9.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.9.0/umd/react-dom.production.min.js"></script>