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