You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React中如何给拆分的DD/MM/YYYY日期输入框预填充父组件传值

实现方案

核心逻辑是新增对父级传入dateInputValue的监听,合法值拆分后同步到三个输入框状态即可,同时做边界处理避免触发不必要的回调。

第一步:可选首屏渲染优化

直接在useState初始化时读取dateInputValue赋值,避免首次渲染出现输入框空值后再闪现有值的情况:

// 初始化时优先读取传入的合法初始值
const initDateSegments = dateInputValue?.match(/^\d{2}-\d{2}-\d{4}$/)?.[0]?.split('-') ?? []
const [day, setDay] = useState(initDateSegments[0] ?? "");
const [month, setMonth] = useState(initDateSegments[1] ?? "");
const [year, setYear] = useState(initDateSegments[2] ?? "");

第二步:新增副作用监听值变更

支持父组件动态更新dateInputValue时同步到子组件输入框,同时同步缓存值避免触发不必要的onValueChange回调:

useEffect(() => {
  // 过滤空值和格式非法的入参
  if (!dateInputValue || !/^\d{2}-\d{2}-\d{4}$/.test(dateInputValue)) return;
  const [inputDay, inputMonth, inputYear] = dateInputValue.split('-');
  // 值无变化时跳过更新
  if (inputDay === day && inputMonth === month && inputYear === year) return;

  setDay(inputDay);
  setMonth(inputMonth);
  setYear(inputYear);
  // 同步更新缓存值,避免触发多余的父级回调
  storedDateValue.current = dateInputValue;
}, [dateInputValue, day, month, year]);

完整修改后代码

const DateInput = ({ name, onValueChange, dateInputValue }: Props) => {
  // 初始化时优先读取传入的合法初始值
  const initDateSegments = dateInputValue?.match(/^\d{2}-\d{2}-\d{4}$/)?.[0]?.split('-') ?? []
  const [day, setDay] = useState(initDateSegments[0] ?? "");
  const [month, setMonth] = useState(initDateSegments[1] ?? "");
  const [year, setYear] = useState(initDateSegments[2] ?? "");

  const storedDateValue = useRef(dateInputValue);

  console.log("Base date value: " + dateInputValue);

  const changeDate = useCallback(
    (birthday) => {
      onValueChange(birthday);
    },
    [onValueChange]
  );

  // 监听父级传入的初始值变更,同步到输入框
  useEffect(() => {
    // 过滤空值和格式非法的入参
    if (!dateInputValue || !/^\d{2}-\d{2}-\d{4}$/.test(dateInputValue)) return;
    const [inputDay, inputMonth, inputYear] = dateInputValue.split('-');
    // 值无变化时跳过更新
    if (inputDay === day && inputMonth === month && inputYear === year) return;

    setDay(inputDay);
    setMonth(inputMonth);
    setYear(inputYear);
    // 同步更新缓存值,避免触发多余的父级回调
    storedDateValue.current = dateInputValue;
  }, [dateInputValue, day, month, year]);

  useEffect(() => {
    if (day !== "" && month !== "" && year !== "") {
      const dateValue = `${day}-${month}-${year}`;

      if (storedDateValue.current !== dateValue) {
        storedDateValue.current = dateValue;

        changeDate(dateValue);
      }
    }
  }, [day, month, year, changeDate]);

  return (
    <StyledInputGroup>
      <label htmlFor={`${name}_day`}>
        <span>Day</span>
        <StyledInput
          type="text"
          maxLength="2"
          name={`${name}_day`}
          id={`${name}_day`}
          label="Day"
          value={day}
          onChange={(e) => setDay(e.target.value)}
        />
      </label>
      <label htmlFor={`${name}_month`}>
        <span>Month</span>
        <StyledInput
          type="text"
          maxLength="2"
          name={`${name}_month`}
          id={`${name}_month`}
          label="Month"
          value={month}
          onChange={(e) => setMonth(e.target.value)}
        />
      </label>
      <label htmlFor={`${name}_year`}>
        <span>Year</span>
        <StyledInput
          type="text"
          maxLength="4"
          name={`${name}_year`}
          id={`${name}_year`}
          value={year}
          onChange={(e) => setYear(e.target.value)}
        />
      </label>
    </StyledInputGroup>
  );
};

内容的提问来源于stack exchange,提问作者cts

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 15:24:00