How to use switch statement inside a React component?
I have a React component, and inside the render
method of the component I have something like this:
render() {
return (
<div>
<div>
// removed for brevity
</div>
{ switch(...) {} }
<div>
// removed for brevity
</div>
</div>
);
}
Now the point is that I have two div
elements, one at the top and one at the bottom, that are fixed. In the middle I want to have a switch statement, and according to a value in my state I want to render a different component. So basically, I want the two div
elements to be fixed always, and just in the middle to render a different component each time. I'm using this to implement a multi-step payment procedure). Though, as is the code currently it doesn't work, as it gives me an error saying that switch
is unexpected. Any ideas how to achieve what I want?
Try this, which is way cleaner too: Get that switch out of the render in a function and just call it passing the params you want. For example:
renderSwitch(param) {
switch(param) {
case 'foo':
return 'bar';
default:
return 'foo';
}
}
render() {
return (
<div>
<div>
// removed for brevity
</div>
{this.renderSwitch(param)}
<div>
// removed for brevity
</div>
</div>
);
}
In contrast to other answers, I would prefer to inline the "switch" in the render function. It makes it more clear what components can be rendered at that position. You can implement a switch-like expression by using a plain old javascript object:
render () {
return (
<div>
<div>
{/* removed for brevity */}
</div>
{
{
'foo': <Foo />,
'bar': <Bar />
}[param]
}
<div>
{/* removed for brevity */}
</div>
</div>
)
}
That's happening, because switch
statement is a statement
, but here javascript expects an expression.
Although, it's not recommended to use switch statement in a render
method, you can use self-invoking function to achieve this:
render() {
// Don't forget to return a value in a switch statement
return (
<div>
{(() => {
switch(...) {}
})()}
</div>
);
}
I did this inside the render() method:
render() {
const project = () => {
switch(this.projectName) {
case "one": return <ComponentA />;
case "two": return <ComponentB />;
case "three": return <ComponentC />;
case "four": return <ComponentD />;
default: return <h1>No project match</h1>
}
}
return (
<div>{ project() }</div>
)
}
I tried to keep the render() return clean, so I put my logic in a 'const' function right above. This way I can also indent my switch cases neatly.
I'm not a big fan of any of the current answers, because they are either too verbose, or require you to jump around the code to understand what is going on.
I prefer doing this in a more react component centred way, by creating a <Switch/>
. The job of this component is to take a prop, and only render children whose child prop matches this one. So in the example below I have created a test
prop on the switch, and compared it to a value
prop on the children, only rendering the ones that match.
Example:
const Switch = props => {
const { test, children } = props
// filter out only children with a matching prop
return children.find(child => {
return child.props.value === test
})
}
const Sample = props => {
const someTest = true
return (
<Switch test={someTest}>
<div value={false}>Will display if someTest is false</div>
<div value={true}>Will display if someTest is true</div>
</Switch>
)
}
ReactDOM.render(
<Sample/>,
document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
<div id="react"></div>
You can make the switch as simple or as complex as you want. Don't forget to perform more robust checking of the children and their value props.