Edited
I am trying to make a form that will enable the user to edit an existing citation. The citation is pulled from the backend with an api call. I then assign the values grabbed from the api to the state variables. These state variables is passed as props to the form jsx where they are used in the value
prop of the input field. But for some reason the values assigned to state is not retained by the state and it goes back to its initial state values. I am adding the code as to how the component looks like
const EditEnterCitation = () => {
const [searchParams, setSearchParams] = useSearchParams();
// getting params from the url to pass to the functions
const cat = searchParams.get("cat");
const { id } = useParams();
// state to pass to the value prop in the form input
const [formData, setFormData] = useState({
institution_name: "0",
judge_name: "",
case_no: "",
apelLate_type: "0",
law: "",
point_of_law: "0",
party_name_appelant: "",
party_name_respondent: "",
advocate_petitioner: "",
advocate_respondent: "",
judgements: "",
date_of_order: "",
headnote: "",
references: "",
equivalent_citations: "",
title: "",
});
// state to for select buttonn in the form
const [instName, setInstName] = useState([]);
const [lawChoiceOptions, setlawChoiceOptions] = useState([]);
const [pointOfLawOptions, setPointOfLawOptions] = useState([]);
const [appealateType, setAppealateType] = useState([]);
// getting the choices for select from backend
const allChoices = useQuery(
["allChoices", cat],
() => getAllChoices(cat),
{
enabled: cat !== null,
refetchOnWindowFocus: false,
onSuccess: (response) => {
// setting law choices
if (response.data.law) {
let arr = response.data.law.map((element, index) => {
return { value: element.law_name, label: element.law_name };
});
setlawChoiceOptions(arr);
}
// setting point of law options
setPointOfLawOptions(response.data.pol);
// setting appealate type
setAppealateType(response.data.appeal);
// setting ins choices
if (response.data.ins.length) {
setInstName(response.data.ins);
} else {
let court_names = [];
let tribunal_name = [];
if (response.data.ins.ins_court.length > 0) {
court_names = response.data.ins.ins_court;
}
if (response.data.ins.ins_tribunal.length > 0) {
tribunal_name = response.data.ins.ins_tribunal;
}
let ins_names = court_names.concat(tribunal_name);
setInstName(ins_names);
}
},
}
);
// function to get default values of the citation
const getDefaultValues = useQuery(
["detailCitation", id],
() => detailCitation(cat, id),
{
enabled: allChoices.isFetched === true,
refetchOnWindowFocus: false,
onSuccess: (response) => {
setFormData({
institution_name: response.data.institution_name,
judge_name: response.data.judge_name,
case_no: response.data.case_no,
apelLate_type: response.data.apelLate_type,
law: response.data.law,
point_of_law: response.data.point_of_law,
party_name_appelant: response.data.party_name_appelant,
party_name_respondent: response.data.party_name_respondent,
advocate_petitioner: response.data.advocate_petitioner,
advocate_respondent: response.data.advocate_respondent,
judgements: response.data.judgements,
date_of_order: response.data.date_of_order,
headnote: response.data.headnote,
references: response.data.references,
equivalent_citations: response.data.equivalent_citations,
title: response.data.title,
});
},
}
);
// handling form data change for some fields
const handleFormDataChange = (e) => {
setFormData({ ...formData, [e.target.name]: e.target.value });
};
// handling form data change for the judgement
const handleJudgementData = (data) => {
setFormData({ ...formData, judgements: data });
};
const handlePartyAppealData = (data) => {
setFormData({ ...formData, party_name_appelant: data });
};
const handlePartyRespondData = (data) => {
setFormData({ ...formData, party_name_respondent: data });
};
// handling data change of the law choices
const handleOnChangeLaw = (selectedOption) => {
let newArray = [];
selectedOption.map((element) => {
newArray.push(element.value);
});
setFormData({ ...formData, law: newArray.toString() });
};
// hadling sumbimission of citation
const handleFormDataSubmit = async (e) => {
e.preventDefault();
try {
setProgress(80);
let response = await addCitation(cat, formData);
if (response.status === 201) {
toastNotification(
`Citation Uploaded to ${cat.toUpperCase()}`,
`success`
);
setProgress(100);
goToTop();
} else {
toastNotification(`Server Error. Could not upload citation`, `error`);
setProgress(100);
}
} catch (error) {}
};
useEffect(() => {
console.count("formData Appearing");
console.log(formData);
});
return (
<>
<LoadingBar
color="red"
progress={progress}
onLoaderFinished={() => setProgress(0)}
height={4}
/>
<Helmet>
<title>Enter Citation</title>
</Helmet>
<Wrapper>
<FormContainer onSubmit={handleFormDataSubmit}>
<EditInsFormElements
cat={cat}
handleFormDataChange={handleFormDataChange}
formData={formData}
handleJudgementData={handleJudgementData}
handleOnChangeLaw={handleOnChangeLaw}
instName={instName}
/>
<EditOtherFormElements
cat={cat}
handleFormDataChange={handleFormDataChange}
formData={formData}
handleJudgementData={handleJudgementData}
handleOnChangeLaw={handleOnChangeLaw}
lawChoiceOptions={lawChoiceOptions}
pointOfLawOptions={pointOfLawOptions}
appealateType={appealateType}
handlePartyAppealData={handlePartyAppealData}
handlePartyRespondData={handlePartyRespondData}
/>
<FormFooter>
<UploadBtn disabled={disableSubmit()} type="submit">
Upload Citation
</UploadBtn>
</FormFooter>
</FormContainer>
</Wrapper>
</>
);
};
the jsx inside the EditInsFormElements and EditOtherFormElements looks like this
<label className="required-field" htmlFor="apelLate_type">
Apellate Type*
</label>
<select
name="apelLate_type"
id="apelLate_type"
value={formData.apelLate_type}
onChange={handleFormDataChange}
required
>
<option value="0" disabled hidden>
Select
</option>
{appealateType &&
appealateType.length &&
appealateType.map((element, index) => {
return (
<option key={index} value={element.appealate_type}>
{element.appealate_type}
</option>
);
})}
</select>
<label className="required-field" htmlFor="case_no">
Case No*
</label>
<TextArea
name="case_no"
id="case_no"
value={formData.case_no}
onChange={handleFormDataChange}
required
/>
<label className="required-field" htmlFor="title">
Title*
</label>
<input
type="text"
name="title"
value={formData.title}
onChange={handleFormDataChange}
required
/> ....
And the state behaviour in the console that I have produced using useEffect is attached below
Question Why is this alternating behaviour seen in the console is caused and how to rectify it so that the state retains the values grabbed and assigned from the backend.