5

I'm currently doing this to conditionally render certain Components:

render() {
    return (
        <React.Fragment>
            <div id="call_notes_app" className="row">
                <NavTree onNavChange={this.changeActiveGroup} />
                {this.state.shownGroup == 1 && <DiscoveryGroup/>}
                {this.state.shownGroup == 2 && <FinancialGroup/>}
                {this.state.shownGroup == 3 && <SalesStuffGroup/>}
            </div>
        </React.Fragment>
    );
}

When I try to use a switch statement, it doesn't work (I get ERROR ABORT in the console):

render() {
    return (
        <React.Fragment>
            <div id="call_notes_app" className="row">
                <NavTree onNavChange={this.changeActiveGroup} />

                {
                    switch(this.state.shownGroup) {
                        case 1:
                            <DiscoveryGroup/>
                            break;
                        case 2:
                            <FinancialGroup />
                            break;
                        default:
                            <SalesStuffGroup />
                    }
                }
            </div>
        </React.Fragment>
    );
}

Is there a way to do this using switch?

3 Answers 3

15

{} is for a single statement. A cleaner way would be switching before the return statement:

render() {
    let component = null;
    switch(this.state.shownGroup) {
      case 1:
        component = <DiscoveryGroup />;
        break;
      case 2:
        component = <FinancialGroup />;
        break;
      default:
        component = <SalesStuffGroup />;
    }

    return (
        <React.Fragment>
            <div id="call_notes_app" className="row">
                <NavTree onNavChange={this.changeActiveGroup} />
                {component}
            </div>
        </React.Fragment>
    );
}

If you eventually have many dynamic components, splitting things out to seperate methods cleans things up even more:

renderGroup(group) {
    switch (group) {
      case 1:
        return <DiscoveryGroup />;
      case 2:
        return <FinancialGroup />;
      default:
        return <SalesStuffGroup />;
    }
}

render() {
    return (
        <React.Fragment>
            <div id="call_notes_app" className="row">
                <NavTree onNavChange={this.changeActiveGroup} />
                {this.renderGroup(this.state.shownGroup)}
            </div>
        </React.Fragment>
    );
}
Sign up to request clarification or add additional context in comments.

Comments

1

React requires expressions in the {} block, therefore you need to wrap the switch statement into an IIFE:

 {(() => {
   switch(this.state.shownGroup) {
     case 1:
         return <DiscoveryGroup/>
         break;
     case 2:
         return <FinancialGroup />
         break;
     default:
         return <SalesStuffGroup />
   }
 })()}

But i personally would actually prefer an Immeadiately Accessed Array Literal (IAAL):

 {[,<DiscoveryGroup/>, <FinancialGroup />][this.state.showGroup] || <SalesStuffGroup />}

2 Comments

The second method will run constructors of all the components but first, which is not cool. The first approach will create a new function on every render, which is cooler, but still unnecessary.
Don't need breaks after return statement.
0

The switch is nice, but in these cases it might be more elegant to use an object (or array with find):

const LayoutComponents {
    'simple': SimpleLayout,
    'wild': WildLayout,
    'freudian': FreudianLayout,
}


const Layout = LayoutComponents[props.layout];

if (!Layout) {
   console.error('Drama Alert');
   // throw error or return
}

// render. 
return <Layout {...props}>{props.children}</Layout>

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.