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

时间:2019-09-18 23:51:41

标签: 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),而年字段也将其值递增。

任何人都可以解释这里可能发生的情况以及如何解决吗?

2 个答案:

答案 0 :(得分: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。

答案 1 :(得分:1)

编辑: 通过这种方式进行处理,您也可以将一个月内的几天总计更改为此类,而无需将其硬编码为31。这只是一个示例设计使您变得灵活。

我个人不理解您为什么将const int darkness_threshold = 128; // you need to determine what threshold to use cv::Mat mat = get_image_from_device(); cv::Mat hsv; cv::cvtColor(mat, hsv, CV_BGR2HSV); const auto result = cv::mean(hsv); // cv::mean() will return 3 numbers, one for each channel: // 0=hue // 1=saturation // 2=value (brightness) if (result[2] < darkness_threshold) { process_dark_image(mat); } else { process_light_image(mat); } 传递给子组件。.我看不出这样做的意义或这样做的好处。

我认为问题出在您处理设计的方式上。

每次更改setDateconst yearconst day都会再次运行..这是您应该使用const month的地方。只需传递{{ 1}}作为道具,然后处理state组件本地的该日期的所有更改...让孩子接触到父级并更改其状态直接令我感到奇怪。

这种事情就是我要处理的方式-感觉更干净了。

date
DatePicker