I have been asked to solve a problem using any front-end framework ( reactjs in my case ) . Basically there is a form for adding a car and there can be say a type of car like 'SUV','semitruck','racecar' and so on...
In the form there needs to be different components rendered based on the type of car you want to add ( e.g. SUV has 2 inputs , racecar has 5 inputs ) how can i dynamically render these components and get their input values without doing if statements?
So pretty much i want to avoid doing this :
{typeSelection == "SUV" && (
<SVUInput
size={sizeInput}
changeSize={(str) => setSizeInput(str)}
/>
)}
{typeSelection == "Bus" && (
<WeightInput
Weight={weightInput}
changeWeight={(str) => setWeightInput(str)}
/>
)}
{typeSelection == "Semitruck" && (
<DimensionInput
wheels={wheels}
length={length}
changeWheels={(n) => setWheels(n)}
changeLength={(str) => setLength(str)}
/>
)}
I tried doing this but doesnt work ( im guessing react doesnt re-render here )
const [dynamicInputs, setDynamicInputs] = React.useState<any>({
SUV: <SUVInput size={sizeInput} changeSize={(str) => setSizeInput(str)} />,
bus: <BusInput weight={weightInput} changeSize={(n) => setSizeInput(n)} />,
semitruck: <SemitruckInput wheels={wheelsInput} changeWheels={(n) => setWheelsInput(n)}
color={colorInput} changeColor={(n) => setColorInput(n)} />,
});
Instead the above code although renders the component , the input does not change when i type into it, it remains blank , i assume it doesnt trigger react to re-render the state
So pretty much instead of making many if statements that would slow down the front-end , Im trying to make it dynamic so that it only takes O(1) time to render the correct form inputs.
CodePudding user response:
I pretty like your solution because that's the thing I'm used to do really often. Your issue is about storing the components inside useState
, because they are initialized there when component mounts and they just stay in the same state for the whole component lifetime. The solution is pretty simple as well - just move it out of the state so they do react to state and props changes.
https://codesandbox.io/s/frosty-wozniak-xcy2bv?file=/src/App.js:114-536
export default function App() {
const [size, setSize] = useState(0);
const [currentComponent] = useState('SUV');
const components = {
SUV: <SuvComponent size={size} />,
};
return (
<div className="App">
<input onChange={(e) => setSize(e.target.value)} />
{components[currentComponent]}
</div>
);
}
CodePudding user response:
it works if i implement the UseState method and then have a useEffect to update it like so :
React.useEffect(() => {
setDynamicInputs({
SUV: (
<SUV size={sizeInput} changeSize={(str) => setSizeInput(str)} />
),
bus: (
<WeightInput
Weight={weightInput}
changeWeight={(str) => setWeightInput(str)}
/>
),
});
}, [dynamicInputs]);