19

I have four components imported in my react app. How can i render one of the component conditionally (based on props). This is what i'm trying to do

<ReactSVGPanZoom
      //switch(this.props.Selected){
      // case '1': render <ComponentOne/>; break;
      // case '2': render <ComponentTwo/>; break;
      // case '3': render <ComponentThree/>; break;
      // case '4': render <ComponentFour/>; break;
      // default: render <ComponentOne/>
        }
</ReactSVGPanZoom>
Mayank Shukla
  • 100,735
  • 18
  • 158
  • 142
Vishnu
  • 1,611
  • 1
  • 14
  • 27

7 Answers7

27

Directly it's not allowed, because we can't put any statement inside JSX. You can do one thing, put the code (switch logic) inside a function and call that function, and return the correct component from that.

Check doc for: Embedding Expressions in JSX

Like this:

<ReactSVGPanZoom
    {this.renderComponent()}
</ReactSVGPanZoom>


renderComponent(){
    switch(this.props.Selected){
        case '1': return <ComponentOne/>;
        case '2': return <ComponentTwo/>;
        case '3': return <ComponentThree/>;
        case '4': return <ComponentFour/>;
        default: return <ComponentOne/>
    }
}

Suggestion:

break is not required after return.

Mayank Shukla
  • 100,735
  • 18
  • 158
  • 142
7

You can just get the component from the switch (either in a function or in-line in render) and render it as a child of ReactSvgPanZoom, like so:

getComponent(){
  switch(this.props.Selected){
    case '1': 
      return <ComponentOne/>;
    case '2': 
      return <ComponentTwo/>; 
    // .. etc
    default: 
      return <ComponentOne/>
  }
}
render() {
    return (<ReactSVGPanZoom>
        {this.getComponent()}
      </ReactSVGPanZoom>);
  }
dashton
  • 2,684
  • 1
  • 18
  • 15
4

You can create a const and use it whenever you need:

import React from "react";

export const myComponents = {
  Component1: <Component1 />,
  Component2: <Component2 />,
  Component3: <Component3 />,
  Component4: <Component4 />,
}

now in your main component:

import React from "react";
import {myComponents} from "./const";

...
render() {
  return (
    <div>
      {myComponents[this.props.Selected]}
    </div>
  )
}

https://codesandbox.io/s/mzn5x725vx

max li
  • 2,417
  • 4
  • 30
  • 44
  • I was trying to find a better solution. But realizing that I am already using imho something that @max li suggested already. So I think this is the best answer for the question above. – vik Mar 28 '21 at 17:50
4
render() {
  return (
    <div>
      {
        (() => {
          switch(this.props.value) {
            case 1:
              return this.myComponentMethod();
              break;
            case 2: 
              return () => { return <AnotherComponent/> }; 
              break;
            case 3:
              return <div>1</div>; 
            break;
            default: return null; break;
          }
        }).call(this)
      }
    </div>
  )
}
Sasha Kos
  • 2,480
  • 2
  • 22
  • 37
  • 1
    not sure about this solution, basically it is going to create a new function and self invoking it each time you render the component, which is something usually not desired – GibboK Mar 12 '20 at 16:06
  • add the switch to dedicated function – GibboK Mar 12 '20 at 16:06
  • Its actually not a real life example, dedicated function is definitely best solution for this. My code just shows in fancy way that it is possible – Sasha Kos Mar 12 '20 at 19:53
3

There's a construct for this purpose: Do Expression

You can use it like this:

<ReactSVGPanZoom
    {do {
        switch (this.props.Selected) {
            case '1': <ComponentOne/>; break;
            case '2': <ComponentTwo/>; break;
            case '3': <ComponentThree/>; break;
            case '4': <ComponentFour/>; break;
            default: <ComponentOne/>;
        }
    }}
</ReactSVGPanZoom>

Just remember that you don't use return in do expressions and your last expression in the do expression will be the returned value. So even if you put a semicolon after switch it ruins things.

Sassan
  • 2,187
  • 2
  • 24
  • 43
0
export default function FunctionName(props) {
  return (
    <div>
      {
        (() => {
          switch (props.value) {
            case 1:
              return <p>Case 1<;
              break;
            case 2:
              return () => { return <AnotherComponent /> };
              break;
            case 3:
              return <div>1</div>;
              break;
            default: return null; break;
          }
        })
      }
    </div>
  )
}
kartik tyagi
  • 6,256
  • 2
  • 14
  • 31
0

You can use an array index as dependency like this:

<Box>
    {
      {
        0: <ComponentOne/>,
        1: <ComponentTwo/>,
        2: <ComponentThree/>,
      }[arrayIndex]         // arrayIndex as dependency
    }
</Box>
Java bee
  • 2,522
  • 1
  • 12
  • 25