我尝试重构两个组件DateTimeFormField
和TimeFormField
,因为这两个组件共享几乎相同的逻辑和输出。
我想到的一种方法是导出功能组件DateTimeFormField
中的函数,但这似乎不是一个干净的解决方案,因为两个组件(声明的变量)之间仍然存在相同的逻辑。
从一些研究来看,自定义钩子似乎可以解决这里的代码重复问题,但两个组件都是无状态的,所以我不完全确定自定义钩子是否会对我的情况造成过度影响。
DateTimeFormField.tsx
function DateTimeFormField({
fieldName,
flatFieldName,
validationMessage,
value,
onChange,
onBlur
}: FieldProps) {
const valueAsStr = value === undefined ?
"" :
value as string;
const dateFromValue = valueAsStr.substring(0, 10);
const timeFromValue = valueAsStr.substring(11, 16);
const todayDateObj = new Date();
const todayDate = todayDateObj.toISOString().slice(0, 10);
function onDateChange(dateUpdate: string) {
const date = dateUpdate || "0000-00-00";
const time = timeFromValue || "00:00";
return onChange(flatFieldName, date + "T" + time + ":00+00:00");
}
function onTimeChange(timeUpdate: string) {
const date = dateFromValue || todayDate;
const time = timeUpdate || "00:00";
return onChange(flatFieldName, date + "T" + time + ":00+00:00");
}
function onTimeBlur(timeUpdate: string, fieldName: string) {
onTimeChange(timeUpdate);
onBlur(fieldName);
}
return (
<FormGroup
validationMessage={validationMessage}
data-element="date-time-form-field-form-group">
<FieldLabel fieldName={fieldName} />
<div className="date-time-combo">
<DatePicker
inputProps={{"data-element": "date-form-field-input"}}
dateFormat="YYYY-MM-DD"
initialValue={dateFromValue}
onChange={(date) => onDateChange(date.isoFormattedDate)}
onBlur={() => onBlur(flatFieldName)}
/>
<TimePicker
data-element="time-form-field-input"
timeFormat="HH:mm"
initialValue={timeFromValue}
onSelect={(time) => onTimeChange(time.rawValue)}
onBlur={(time) => onTimeBlur(time.rawValue, flatFieldName)}
/>
</div>
</FormGroup>
);
}
export default memo(DateTimeFormField);
TimeFormField.tsx
function TimeFormField({
fieldName,
flatFieldName,
validationMessage,
value,
onChange,
onBlur
}: FieldProps) {
const valueAsStr = value === undefined ?
"" :
value as string;
const dateFromValue = valueAsStr.substring(0, 10);
const timeFromValue = valueAsStr.substring(11, 16);
const todayDateObj = new Date();
const todayDate = todayDateObj.toISOString().slice(0, 10);
function onTimeChange(timeUpdate: string) {
const date = dateFromValue || todayDate;
const time = timeUpdate || "00:00";
return onChange(flatFieldName, date + "T" + time + ":00+00:00");
}
function onTimeBlur(timeUpdate: string, fieldName: string) {
onTimeChange(timeUpdate);
onBlur(fieldName);
}
return (
<FormGroup
validationMessage={validationMessage}
data-element="time-form-field-form-group">
<FieldLabel fieldName={fieldName} />
<div className="time-combo">
<TimePicker
data-element="time-form-field-input"
timeFormat="HH:mm"
initialValue={timeFromValue}
onSelect={(time) => onTimeChange(time.rawValue)}
onBlur={(time) => onTimeBlur(time.rawValue, flatFieldName)}
/>
</div>
</FormGroup>
);
}
export default memo(TimeFormField);
1条答案
按热度按时间nlejzf6q1#
您可以添加一个属性来指定是否要选择日期。然后您可以基于该属性有条件地呈现。
一般形式是
但是,您也可以将条件部分嵌入到单个
return
语句中。例如,如果将
includeDate: boolean
添加到DateTimeFormField
组件中的props,则可以渲染以下内容:所以你只需要一个组件,然后根据 prop 渲染你想要渲染的东西。