How to show current values for select inputs with or without React Hook Form?

Issue

I’m working on an Ionic React App and I should update some data in an endpoint using a form. When I open the form, I must show the current values for the inputs. I’m facing difficulties for select inputs. When I open the form, nothing is selected on “Title” & “Salutation”.

With React Hook Form:

import {
  IonContent,
  IonPage,
  IonItem,
  IonLabel,
  IonButton,
  IonInput,
  IonSelect,
  IonSelectOption,
} from "@ionic/react";
import "../Home.css";
import React, { useState, useEffect } from "react";
import AuthContext from "../../my-context";
import { useHistory } from "react-router-dom";
import axios from "axios";
import { useForm } from "react-hook-form";

const ChangeYourData: React.FC  () > {
  const {
    salutationId,
    setSalutationId,
    title,
    setTitle,
  }  React.useContext(AuthContext);

  const history  useHistory();

  const {
    control,
    register,
    handleSubmit,
    formState: { errors },
    getValues,
  }  useForm({
    mode: "onChange",
  });

  const updateCoreData  () > {
    const data  {
      salutationId: getValues("salutationId"),
      titleId: getValues("title"),
    };

    axios
      .put("/xx/update", data)
      .then((response) > {
        setTitle(response.data.title);
        setSalutationId(response.data.salutation);
        return response.data;
      })
      .catch((error) > {
        setMessage(
          "Sth is wrong!"
        );
        setIserror(true);
      });
  };


  return (
    <React.Fragment>
      <IonPage className"ion-page" id"main-content">
        <IonContent className"ion-padding">
          <h1>My Data </h1>
          <form className"ion-padding" onSubmit{handleSubmit(updateCoreData)}>
            <IonItem>
              <IonLabel position"floating">Title</IonLabel>
              <IonSelect
                {...register("title")}
                defaultValue{title}
              >
                <IonSelectOption value"0"></IonSelectOption>
                <IonSelectOption value"1">Dr</IonSelectOption>
                <IonSelectOption value"2">Ing</IonSelectOption>
                <IonSelectOption value"3">Prof</IonSelectOption>
                <IonSelectOption value"4">Prof.Dr</IonSelectOption>
              </IonSelect>
            </IonItem>
            <IonItem>
              <IonLabel position"floating">Salutation</IonLabel>
              <IonSelect
                {...register("salutationId")}
                defaultValue{salutationId}
              >
                <IonSelectOption value"0"></IonSelectOption>
                <IonSelectOption value"1">Mr.</IonSelectOption>
                <IonSelectOption value"2">Mrs.</IonSelectOption>
                <IonSelectOption value"3">Ms.</IonSelectOption>
                <IonSelectOption value"4">Family</IonSelectOption>
              </IonSelect>
            </IonItem>

            <IonButton
              className"ion-margin-top"
              type"submit"
              expand"block"
            >
              Save
            </IonButton>
          </form>
        </IonContent>
      </IonPage>
    </React.Fragment>
  );
};

export default ChangeYourData;

Without React Hook Form:

import {
  IonContent,
  IonPage,
  IonItem,
  IonLabel,
  IonButton,
  IonInput,
  IonSelect,
  IonSelectOption,
} from "@ionic/react";
import "../Home.css";
import React, { useState, useEffect } from "react";
import AuthContext from "../../my-context";
import { useHistory } from "react-router-dom";
import axios from "axios";
import { useForm } from "react-hook-form";

const ChangeYourData: React.FC  () > {
  const {
    salutationId,
    setSalutationId,
    title,
    setTitle,
  }  React.useContext(AuthContext);

  const history  useHistory();

  const updateCoreData  () > {
    const data  {
      salutationId: salutationId,
      titleId: title,
    };

    axios
      .put("/xx/update", data)
      .then((response) > {
        setTitle(response.data.title);
        setSalutationId(response.data.salutation);
        return response.data;
      })
      .catch((error) > {
        setMessage(
          "Sth is wrong!"
        );
        setIserror(true);
      });
  };


  return (
    <React.Fragment>
      <IonPage className"ion-page" id"main-content">
        <IonContent className"ion-padding">
          <h1>My Data </h1>
          <form className"ion-padding">
            <IonItem>
              <IonLabel position"floating">Title</IonLabel>
              <IonSelect
                value{Object.values(title)}
                onIonChange{(e) > setTitle(e.detail.value!)}

              >
                <IonSelectOption value"0"></IonSelectOption>
                <IonSelectOption value"1">Dr</IonSelectOption>
                <IonSelectOption value"2">Ing</IonSelectOption>
                <IonSelectOption value"3">Prof</IonSelectOption>
                <IonSelectOption value"4">Prof.Dr</IonSelectOption>
              </IonSelect>
            </IonItem>
            <IonItem>
              <IonLabel position"floating">Salutation</IonLabel>
              <IonSelect
                value{Object.values(salutationId)}
                onIonChange{(e) > setSalutationId(e.detail.value!)}
              >
                <IonSelectOption value"0"></IonSelectOption>
                <IonSelectOption value"1">Mr.</IonSelectOption>
                <IonSelectOption value"2">Mrs.</IonSelectOption>
                <IonSelectOption value"3">Ms.</IonSelectOption>
                <IonSelectOption value"4">Family</IonSelectOption>
              </IonSelect>
            </IonItem>

            <IonButton
              className"ion-margin-top"
              type"submit"
              expand"block"
              onClick{(e) > {
                e.preventDefault();
                updateCoreData();
                history.goBack();
              }}
            >
              Save
            </IonButton>
          </form>
        </IonContent>
      </IonPage>
    </React.Fragment>
  );
};

export default ChangeYourData;

How Can I show the current values of select input, considering that :

{JSON.stringify(salutationId)} > {"1":"Mr"}

{JSON.stringify(title)} > {"1":"Dr"}

Title and SalutationId are objects and I cannot change that in backend. I thought I could access and show their value like that:

value{Object.values(salutationId)}

But in this case I get this error when I try to edit the form:

Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.

What do you think?

“react-hook-form”: “^7.1.1”,

Solution

The solution was:

Object.values(title) returns array.

Cast Object.values(title) to String using this trick:

value{"" + Object.values(title)}

The Ion Select Item:

<IonItem>
              <IonLabel position"floating">Title</IonLabel>
              <IonSelect
                value{"" +Object.values(title)}
                {...register("title")}
              >
                <IonSelectOption value"0"></IonSelectOption>
                <IonSelectOption value"1">Dr</IonSelectOption>
                <IonSelectOption value"2">Ing</IonSelectOption>
                <IonSelectOption value"3">Prof</IonSelectOption>
                <IonSelectOption value"4">Prof.Dr</IonSelectOption>
              </IonSelect>
            </IonItem>
            <IonItem>

Answered By – Ani

Leave a Comment