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
相关产品推荐
相关产品推荐

