Reputation: 43
so i have this logic where user click a button then based on the clicked button different component get rendered I was wondering if there is a better method to implement this logic
function Test(props) {
const [component, setComponent] = useState("createPatient")
const [rendered, setRendered] = useState()
function clickHandler(component) {
switch (component) {
case "createPatient":
setRendered(<PatientForm/>)
break
case "findPatient":
setRendered(<FindPatient/>)
break
case "patientsList":
setRendered(<PatientListTable/>)
}
}
return (
<div>
<button onClick={() => clickHandler("createPatient")}>Create Patient</button>
<button onClick={() => clickHandler("findPatient")}>Find Patient</button>
<button onClick={() => clickHandler("patientsList")}>Patients List</button>
{ rendered }
</div>
);
}
export default Test;
Upvotes: 4
Views: 3118
Reputation: 2186
All the other answers here are correct and work well for your use case. I would like to take it a step further and introduce you to code-splitting. It is not necessary but you can always try it.
Presently, you are loading all the components you need at once when your Test
component is loaded. If your imported components in the future get big or complex, the initial rendering can be slowed down.
Code splitting allows you to split your code into small chunks which you can then load on demand.
Here is a working sandbox.
import React, { useState } from "react";
function Test() {
const [component, setComponent] = useState(null);
const LoadComponent = async location => {
const { default: component } = await import(`./components/${location}`);
setComponent(component);
};
return (
<div>
<h1>Click the button to proceed</h1>
<button onClick={() => LoadComponent("PatientForm")}>
Create Patient
</button>
<button onClick={() => LoadComponent("FindPatient")}>
Find Patient
</button>
<button onClick={() => LoadComponent("PatientListTable")}>
Patients List
</button>
{component}
</div>
);
}
export default Test;
If you are using the latest version of React
, you can use React.lazy
. You'll also need to wrap this lazy component with Suspense
. You can modify the above code like this to load components with React.lazy
.
import React, { useState, Suspense } from "react";
const LoadComponent = location => {
const Component = React.lazy(() => import(`./components/${location}`));
setComponent(<Component />);
};
return <Suspense fallback={<div>Loading...</div>}>{component}</Suspense>
Always think in terms of how you can ship the least amount of JavaScript to the user.
Upvotes: 5
Reputation: 5380
the other logic available are roughly similar and doesn't make much of a different in the end result, mostly stylistic and vary in readability; here are two alternative ways;
function Test(props) {
const [index, setIndex] = useState(0);
const components = [<PatientForm/>, <FindPatient/>, <PatientListTable/>];
return (
<div>
<button onClick={() => setIndex(0)}>Patient Form</button>
<button onClick={() => setIndex(1)}>Find Patient</button>
<button onClick={() => setIndex(2)}>Patients List</button>
{components[index]}
</div>
)
or using boolean approach to render components; something like this;
function Test(props) {
const [step, setStep] = useState(0);
return (
<div>
<button onClick={() => setStep(0)}>Patient Form</button>
<button onClick={() => setStep(1)}>Find Patient</button>
<button onClick={() => setStep(2)}>Patients List</button>
{step == 0 && <PatientForm/>}
{step == 1 && <FindPatient/>}
{step == 2 && <PatientListTable/>}
</div>
)
you get the idea
Upvotes: 1
Reputation: 1292
No need to keep components in state, instead you can directly render them using conditionals.
function Test(props) {
const [component, setComponent] = useState("createPatient")
function clickHandler(component) {
switch (component) {
case "createPatient":
setComponent('createPatient)
break
case "findPatient":
setComponent('findPatient')
break
case "patientsList":
setComponent('patientsList')
}
}
return (
<div>
<button onClick={() => clickHandler("createPatient")}>Create Patient</button>
<button onClick={() => clickHandler("findPatient")}>Find Patient</button>
<button onClick={() => clickHandler("patientsList")}>Patients List</button>
{component === 'createPateient' && <PatientForm/>}
{component === 'findPatient' && <FindPatient/>}
{component === 'patientsLis' && <PatientListTable/>}
</div>
);
}
export default Test;
Upvotes: 0