带有 Ionic-React select 的 React-Hooks-Form 不返回 selected 值
React-Hooks-Form with Ionic-React select not returning selected value
我正在尝试通过 React-Hooks-Form 库构建我的组件。我在我的项目中使用 Ionic 5 和 React。除了 select 组件之外,我设法解决了所有组件。它被渲染,它有项目,我可以 select 项目,但在提交时我没有取回对象中的 selected 值。
这是我尝试过的:
export interface CompetitionReuqest {
address: string;
courseId: number;
date: Date;
departmentId: number;
description: string;
documentLink: string;
imageLink: string;
place: string;
title: string;
typeId: number;
isPayable: boolean;
isInternational: boolean;
isGroup: boolean;
}
export interface IHookFormSelectlistProps<T> extends IBaseProps
{
label: string;
value?: string;
data: T[];
placeholder?: string;
displayMember: (item: T) => string;
valueMember: (item: T) => string;
onChange?: (item: T) => void;
reference<TFieldElement extends FieldElement<T>>(rules?: RegisterOptions): (ref: (TFieldElement & Ref) | null) => void;
}
function HookFormSelectList<T>(props: IHookFormSelectlistProps<T>): JSX.Element
{
const [selectedValue, setSelectedValue] = useState<string>();
useEffect(() =>
{
if (props.value)
{
setSelectedValue(props.value);
}
}, []);
return (
<React.Fragment>
<IonItem>
{
props.label &&
<IonLabel position="floating" class="label">{props.label}</IonLabel>
}
<Controller render={ ({ value, onBlur, onChange }) =>
(
<IonSelect
aria-invalid={props.errors && props.errors[props.name] ? "true" : "false"}
aria-describedby={`${props.name}Error`}
onBlur={onBlur}
onIonChange={(e) =>
{
const item: T = props.data.toEnum()
.FirstOrDefault((x: T) => props.valueMember(x) === e.detail.value);
if (props.onChange && item)
{
setSelectedValue(props.valueMember(item));
props.onChange(item);
}
onChange();
}}
value={selectedValue}
defaultValue={selectedValue}
disabled={props.disabled ? props.disabled : false}
placeholder={props.placeholder ? props.placeholder : "Válasszon ..."}>
{props.data.map((item) =>
(
<IonSelectOption
key={props.valueMember(item)}
value={props.valueMember(item)}
class="ion-select">
{props.displayMember(item)}
</IonSelectOption>
))}
</IonSelect>
)}
defaultValue={setSelectedValue}
name={props.name}
control={props.control}
onChangeName="onIonChange" />
</IonItem>
{
props.errors && props.errors[props.name] &&
(
<IonText color="danger" className="ion-padding-start">
<small>
<span role="alert" id={`${props.name}Error`}>
{props.errors[props.name].message}
</span>
</small>
</IonText>
)
}
</React.Fragment>
);
}
export default HookFormSelectList;
export function TypeSelectList(selectProps: IHookFormSelectlistProps<TypeEntity>): JSX.Element
{
return HookFormSelectList<TypeEntity>(selectProps);
}
export function DepartmentSelectList(selectProps: IHookFormSelectlistProps<DepartmentEntity>): JSX.Element
{
return HookFormSelectList<DepartmentEntity>(selectProps);
}
export function CourseSelectList(selectProps: IHookFormSelectlistProps<CourseEntity>): JSX.Element
{
return HookFormSelectList<CourseEntity>(selectProps);
}
以及如何使用它。我需要一个 onChange 事件,也可以在外面使用!
我的 react-hook-form 表单实现[不是所有代码,这只是相关部分]:
const { control, handleSubmit, errors, register } = useForm<CompetitionReuqest>
({
mode: "onChange",
resolver: yupResolver(validationSchema)
});
const onSubmit = async (data: CompetitionReuqest): Promise<void> =>
{
console.log("data:");
console.log({...data});
}
return (
<React.Fragment>
<InformationToast enabled={showToast}
message="A versenyfelhívás feltöltése sikeres volt."
onClick={() => onToasInformationClick()}/>
<form onSubmit={handleSubmit((data: CompetitionReuqest) => onSubmit(data))}>
<IonGrid>
<IonRow>
<IonCol sizeXl="4" sizeLg="12" sizeMd="12" sizeSm="12" sizeXs="12">
<DepartmentSelectList
name="departmentId"
label="Iskola típus"
value={department?.name}
data={departments}
placeholder="Kérem válasszon"
displayMember={(item: DepartmentEntity) => item.name}
valueMember={(item: DepartmentEntity) => itemname}
onChange={(item: DepartmentEntity) => onDepartmentChanged(item)}
control={control}
errors={errors}
reference={register} />
</IonCol>
<IonCol sizeXl="4" sizeLg="12" sizeMd="12" sizeSm="12" sizeXs="12">
<CourseSelectList
name="courseId"
label="Tantárgy"
value={course?.name}
data={courses}
placeholder="Kérem válasszon"
displayMember={(item: CourseEntity) => item.name}
valueMember={(item: CourseEntity) => item.name}
onChange={(item: CourseEntity) => onCourseChanged(item)}
control={control}
errors={errors}
disabled={disableCourses}
reference={register} />
</IonCol>
<IonCol sizeXl="4" sizeLg="12" sizeMd="12" sizeSm="12" sizeXs="12">
<TypeSelectList
name="typeId"
label="Verseny típus"
value={type?.name}
data={types}
placeholder="Kérem válasszon"
displayMember={(item: TypeEntity) => item.name}
valueMember={(item: TypeEntity) => item.name}
onChange={(item: TypeEntity) => onTypeChanged(item)}
control={control}
errors={errors}
reference={register} />
</IonCol>
</IonRow>
<IonRow>
<IonCol>
<IonButton expand="block" type="submit" className="ion-margin-top"
disabled={formState.isValid === false}>
MENTÉS
</IonButton>
</IonCol>
</IonRow>
</IonGrid>
</form>
</React.Fragment>
);
我想你缺少的是这个:
onIonChange = {
(e) => {
/********************* other code */
value = props.valueMember(item);
console.log("value from render before internal onChange:" + value);
onChange(e); //<============= pass the e input to the onChange callback
},
};
我正在尝试通过 React-Hooks-Form 库构建我的组件。我在我的项目中使用 Ionic 5 和 React。除了 select 组件之外,我设法解决了所有组件。它被渲染,它有项目,我可以 select 项目,但在提交时我没有取回对象中的 selected 值。 这是我尝试过的:
export interface CompetitionReuqest {
address: string;
courseId: number;
date: Date;
departmentId: number;
description: string;
documentLink: string;
imageLink: string;
place: string;
title: string;
typeId: number;
isPayable: boolean;
isInternational: boolean;
isGroup: boolean;
}
export interface IHookFormSelectlistProps<T> extends IBaseProps
{
label: string;
value?: string;
data: T[];
placeholder?: string;
displayMember: (item: T) => string;
valueMember: (item: T) => string;
onChange?: (item: T) => void;
reference<TFieldElement extends FieldElement<T>>(rules?: RegisterOptions): (ref: (TFieldElement & Ref) | null) => void;
}
function HookFormSelectList<T>(props: IHookFormSelectlistProps<T>): JSX.Element
{
const [selectedValue, setSelectedValue] = useState<string>();
useEffect(() =>
{
if (props.value)
{
setSelectedValue(props.value);
}
}, []);
return (
<React.Fragment>
<IonItem>
{
props.label &&
<IonLabel position="floating" class="label">{props.label}</IonLabel>
}
<Controller render={ ({ value, onBlur, onChange }) =>
(
<IonSelect
aria-invalid={props.errors && props.errors[props.name] ? "true" : "false"}
aria-describedby={`${props.name}Error`}
onBlur={onBlur}
onIonChange={(e) =>
{
const item: T = props.data.toEnum()
.FirstOrDefault((x: T) => props.valueMember(x) === e.detail.value);
if (props.onChange && item)
{
setSelectedValue(props.valueMember(item));
props.onChange(item);
}
onChange();
}}
value={selectedValue}
defaultValue={selectedValue}
disabled={props.disabled ? props.disabled : false}
placeholder={props.placeholder ? props.placeholder : "Válasszon ..."}>
{props.data.map((item) =>
(
<IonSelectOption
key={props.valueMember(item)}
value={props.valueMember(item)}
class="ion-select">
{props.displayMember(item)}
</IonSelectOption>
))}
</IonSelect>
)}
defaultValue={setSelectedValue}
name={props.name}
control={props.control}
onChangeName="onIonChange" />
</IonItem>
{
props.errors && props.errors[props.name] &&
(
<IonText color="danger" className="ion-padding-start">
<small>
<span role="alert" id={`${props.name}Error`}>
{props.errors[props.name].message}
</span>
</small>
</IonText>
)
}
</React.Fragment>
);
}
export default HookFormSelectList;
export function TypeSelectList(selectProps: IHookFormSelectlistProps<TypeEntity>): JSX.Element
{
return HookFormSelectList<TypeEntity>(selectProps);
}
export function DepartmentSelectList(selectProps: IHookFormSelectlistProps<DepartmentEntity>): JSX.Element
{
return HookFormSelectList<DepartmentEntity>(selectProps);
}
export function CourseSelectList(selectProps: IHookFormSelectlistProps<CourseEntity>): JSX.Element
{
return HookFormSelectList<CourseEntity>(selectProps);
}
以及如何使用它。我需要一个 onChange 事件,也可以在外面使用! 我的 react-hook-form 表单实现[不是所有代码,这只是相关部分]:
const { control, handleSubmit, errors, register } = useForm<CompetitionReuqest>
({
mode: "onChange",
resolver: yupResolver(validationSchema)
});
const onSubmit = async (data: CompetitionReuqest): Promise<void> =>
{
console.log("data:");
console.log({...data});
}
return (
<React.Fragment>
<InformationToast enabled={showToast}
message="A versenyfelhívás feltöltése sikeres volt."
onClick={() => onToasInformationClick()}/>
<form onSubmit={handleSubmit((data: CompetitionReuqest) => onSubmit(data))}>
<IonGrid>
<IonRow>
<IonCol sizeXl="4" sizeLg="12" sizeMd="12" sizeSm="12" sizeXs="12">
<DepartmentSelectList
name="departmentId"
label="Iskola típus"
value={department?.name}
data={departments}
placeholder="Kérem válasszon"
displayMember={(item: DepartmentEntity) => item.name}
valueMember={(item: DepartmentEntity) => itemname}
onChange={(item: DepartmentEntity) => onDepartmentChanged(item)}
control={control}
errors={errors}
reference={register} />
</IonCol>
<IonCol sizeXl="4" sizeLg="12" sizeMd="12" sizeSm="12" sizeXs="12">
<CourseSelectList
name="courseId"
label="Tantárgy"
value={course?.name}
data={courses}
placeholder="Kérem válasszon"
displayMember={(item: CourseEntity) => item.name}
valueMember={(item: CourseEntity) => item.name}
onChange={(item: CourseEntity) => onCourseChanged(item)}
control={control}
errors={errors}
disabled={disableCourses}
reference={register} />
</IonCol>
<IonCol sizeXl="4" sizeLg="12" sizeMd="12" sizeSm="12" sizeXs="12">
<TypeSelectList
name="typeId"
label="Verseny típus"
value={type?.name}
data={types}
placeholder="Kérem válasszon"
displayMember={(item: TypeEntity) => item.name}
valueMember={(item: TypeEntity) => item.name}
onChange={(item: TypeEntity) => onTypeChanged(item)}
control={control}
errors={errors}
reference={register} />
</IonCol>
</IonRow>
<IonRow>
<IonCol>
<IonButton expand="block" type="submit" className="ion-margin-top"
disabled={formState.isValid === false}>
MENTÉS
</IonButton>
</IonCol>
</IonRow>
</IonGrid>
</form>
</React.Fragment>
);
我想你缺少的是这个:
onIonChange = {
(e) => {
/********************* other code */
value = props.valueMember(item);
console.log("value from render before internal onChange:" + value);
onChange(e); //<============= pass the e input to the onChange callback
},
};