Reputation: 115
In my ReactHooks/Typescript app, I have a Navigation component, that renders a PatientInfo component. The PatientInfo child is rendered conditionally based on what props it is passed, as decided by a searchbox in another child component - MyPatients.
In this structure, I am getting the following error:
Navigation.tsx:
// code....
<Route exact path="/" component={MyPatients} />
<Route
exact
path="/Pasient"
render={() => (
<PatientInfo
setName={setName}
setSchema={setSchema}
patientID={patientID}
/>
)}
/>
// code....
MyPatients:
const MyPatients = (props: { history: History }) => {
localStorage.clear();
const [patientID, setPatientID] = useState(
localStorage.getItem('myData') || '',
);
useEffect(() => {
localStorage.setItem('myData', patientID);
}, [patientID]);
return (
<>
<div className="search-container"></div>
<Row gutter={[60, 40]} justify={'center'}>
<Col span={1000}>
<p>Søk med personnummer for å finne en pasient</p>
<Search
style={{ width: 400 }}
className="search-bar"
placeholder="Søk etter en pasient!"
onSearch={(value: string) => setPatientID(value)}
/>
</Col>
</Row>
{patientID &&
props.history.push({ pathname: 'Pasient', state: patientID })}
</>
);
};
export default MyPatients;
I am not familliar with this issue, and don't understand what's happening. My educated guess is that React doesn't like the fact that the state of the parent component is being updated by functions passed to the children, which again are dependant on the props passed along with it. Am I on to something? Any ideas as to what is causing this if not?
Any help is appreciated.
Upvotes: 2
Views: 3587
Reputation: 2866
You are navigating with history.push
on each render.
As @HMR mentioned in the comment, you have to remove navigation from JSX template and add it into a separate effect.
const MyPatients = (props: { history: History }) => {
localStorage.clear();
const [patientID, setPatientID] = useState(
localStorage.getItem("myData") || ""
);
useEffect(() => {
localStorage.setItem("myData", patientID);
}, [patientID]);
// separate effect here
useEffect(() => {
if (patientID) {
props.history.push({ pathname: "Pasient", state: patientID });
}
}, [props, patientID]);
return (
<>
<div className="search-container"></div>
<Row gutter={[60, 40]} justify={"center"}>
<Col span={1000}>
<p>Søk med personnummer for å finne en pasient</p>
<Search
style={{ width: 400 }}
className="search-bar"
placeholder="Søk etter en pasient!"
onSearch={(value: string) => setPatientID(value)}
/>
</Col>
</Row>
</>
);
};
export default MyPatients;
EDIT
This might cause your error:
<PatientInfo
setName={setName}
setSchema={setSchema}
patientID={patientID}
/>
If you call setName
or setSchema
on render of PatientInfo
then Navigation
state gets updated before PatientInfo
render is finished.
Upvotes: 2