带有 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
   },
 };