Home > Blockchain >  ReactJs How to dynamically render components based on value
ReactJs How to dynamically render components based on value

Time:11-18

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]);
  • Related