I have a component which has been used at multiple places. When rendered, the radio button should be selected based on existingValues.
type GynaecologicHistoryOptionsProps = {
optLabel: string;
name: keyof GynacologicHistoryDataModel;
id: string;
textAreaId?: keyof GynacologicHistoryDataModel | null;
gynaHistOptionsdata: (data: GynaecologicHistoryOptionsData) => void;
labelDetails?: string;
existingValues: GynacologicHistoryDataModel;
crudTranslations: CrudTranslations;
translations: TranslationsModel;
};
export const GynaecologicHistoryOptions = (
props: GynaecologicHistoryOptionsProps
) => {
const {
optLabel,
name,
id,
textAreaId,
gynaHistOptionsdata,
labelDetails,
existingValues,
crudTranslations,
translations,
} = props;
const [showTextArea, setShowTextArea] = useState<boolean>(false);
const [radioBtnValue, setRadioBtnValue] = useState<number>(
existingValues[name] === 1 ? 1 : 0
);
const [inputs, setInputs] = useState<GynaecologicHistoryOptionsData>(() => {
const initialState = {
[name]: existingValues[name] === 1 ? 1 : 0,
textAreaId: textAreaId ? existingValues[textAreaId] : "",
};
if (textAreaId) {
initialState[textAreaId] = existingValues[textAreaId] || "";
}
return initialState;
});
useEffect(() => {
const newValue = existingValues[name] === 1 ? 1 : 0;
if (inputs[name] !== newValue) {
setInputs((values) => ({
...values,
[name]: newValue,
}));
setRadioBtnValue(newValue);
}
}, [existingValues, name]);
const handleChange = (
value: number | string,
name: keyof GynacologicHistoryDataModel
) => {
let newValue: number = 0;
if (typeof value === "string") {
newValue = parseInt(value);
}
switch (name) {
case "uterine_surgery":
setShowTextArea(
newValue === 1 && (textAreaId ?? "").length > 0 ? true : false
);
setRadioBtnValue(newValue);
setInputs((values) => ({ ...values, [name]: value }));
break;
default:
setRadioBtnValue(newValue);
setInputs((values) => ({ ...values, [name]: newValue }));
}
};
const handleInputChange = (event: ChangeEvent<HTMLInputElement>) => {
const name = event.target.name;
const value = event.target.value;
setInputs((values) => ({ ...values, [name]: value }));
};
useEffect(() => {
gynaHistOptionsdata({ ...inputs });
}, [inputs, gynaHistOptionsdata]);
return (
<>
<FormGroup id={id}>
<FormControl>
<FormLabel sx={{ textAlign: "left" }}>{optLabel}*</FormLabel>
<RadioGroup
name={name}
id={id}
row
onChange={(e) =>
handleChange(e.target.value as unknown as number, name)
}
value={radioBtnValue}
>
<FormControlLabel
value="0"
control={<Radio data-testid={`${id}_no`} />}
label={crudTranslations?.label_no}
/>
<FormControlLabel
value="1"
control={<Radio data-testid={`${id}_yes`} />}
label={crudTranslations?.label_yes}
/>
</RadioGroup>
</FormControl>
</FormGroup>
{(inputs[name] === 1 && (textAreaId ?? "").length > 0) || showTextArea ? (
<>
<FormControl fullWidth>
<TextField
label={labelDetails}
margin="normal"
fullWidth
multiline
type="text"
data-testid={textAreaId}
name={textAreaId || "details"}
value={inputs[textAreaId as string] || ""}
onChange={(e: ChangeEvent<HTMLInputElement>) =>
handleInputChange(e)
}
/>
</FormControl>
</>
) : null}
</>
);
};
I tried using useEffect as well. But in that case it won't allow me to change the radio buttons. when radio buttons are changed, it keeps fluctuating and sets the value from useeffect.