为什么更改一个输入中的值也会更改另一个输入中的值?

  • 本文关键字:另一个 一个 reactjs react-hooks
  • 更新时间 :
  • 英文 :


我正在尝试学习和试验 React 钩子。对于一个小型测试项目,我想在用户更改显示模式或更改日期时更新日历网格。

这是Calendar.jsx.状态存储在此处。datesetDate作为道具传递给CalendarDatePicker

import React, {useState} from 'react';
import PropTypes from 'prop-types';
import CalendarDisplayMode from './CalendarDisplayMode';
import CalendarDatePicker from './CalendarDatePicker';
import CalendarGrid from './CalendarGrid';
const Calendar = props => {
const [date, setDate] = useState(props.date);
const [mode, setMode] = useState(props.mode);
return (
<div className="bg-light border border-dark rounded p-1">
<CalendarDisplayMode mode={mode} setMode={setMode} />
<CalendarDatePicker date={date} setDate={setDate} />
<CalendarGrid displayDate={date} displayMode={mode} />
</div>
);
}
Calendar.propTypes = {
date: PropTypes.instanceOf(Date).isRequired,
mode: PropTypes.oneOf(['day', 'week', 'month', 'year']).isRequired
}
export default Calendar;

这是CalendarDatePicker.jsx.当任何输入更改时setDate将被调用并传递新日期。这应该更新Calendar中的状态。

import React from 'react';
import PropTypes from 'prop-types';
const CalendarDatePicker = ({date, setDate}) => {
const year = date.getFullYear();
const month = date.getMonth() + 1;
const day = date.getDate();
const handleYearChange = event => setDate(new Date(event.target.value, month, day));
const handleMonthChange = event => setDate(new Date(year, event.target.value - 1, day));
const handleDayChange = event => setDate(new Date(year, month, event.target.value));
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="31"
value={day}
onChange={handleDayChange} />
</div>
</div>
);
}
CalendarDatePicker.propTypes = {
date: PropTypes.instanceOf(Date).isRequired,
setDate: PropTypes.func.isRequired
}
export default CalendarDatePicker;

但我观察到奇怪的行为。如果我递增或递减年份字段中的数字,则月份字段将增加其值。如果我递增或递减月份字段,则其他字段都不会更改值(如预期的那样(。如果我递增或递减日字段中的数字,则月份字段将递增其值。如果我将日字段中的数字递增或递减到足够多,则月份字段将滚动(从 12 到 1(,并且年份字段也会增加其值。

谁能解释一下这里可能发生的事情以及如何解决它?

const handleYearChange = event => setDate(new Date(event.target.value, month, day));
const handleMonthChange = event => setDate(new Date(year, event.target.value - 1, day));
const handleDayChange = event => setDate(new Date(year, month, event.target.value));

handleYearChangehandleDayChange你正在通过month这实际上是date.getMonth() + 1- 你需要做month - 1.

这就是为什么当年份或日期发生变化时,您的月份会增加 1。

编辑: 以这种方式处理它,您还可以更改一个月中天数等的总数,而无需将其硬编码为 31。只是此设计如何让您变得灵活的一个例子。

我个人不明白你为什么要setDate传递给子组件。.我看不出这有什么意义,也不明白你从中获得什么。

在我看来,问题源于你如何处理你的设计。

每次出现问题时,const yearconst dayconst 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>

相关内容

  • 没有找到相关文章

最新更新