score:372
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>
);
}
score:-1
This is another approach.
render() {
return {this[`renderStep${this.state.step}`]()}
renderStep0() { return 'step 0' }
renderStep1() { return 'step 1' }
score:0
This answer is specifically intended to address this "duplicate" question, by @tonyfat, regarding how to use conditional expressions to handle the same task.
Avoiding statements here seems like more trouble than it's worth, but this script does the job as the snippet demonstrates:
// Runs tests
let id = 0, flag = 0;
renderByFlag(id, flag); // jobId out of range
id = 1; // jobId in range
while(++flag < 5){ // active flag ranges from 1 to 4
renderByFlag(id, flag);
}
// Defines a function that chooses what to render based on two provided values
function renderByFlag(jobId, activeFlag){
jobId === 1 ? (
activeFlag === 1
? render("A (flag = 1)")
: activeFlag === 2
? render("B (flag = 2)")
: activeFlag === 3
? render("C (flag = 3)")
: pass(`flag ${activeFlag} out of range`)
)
: pass(`jobId ${jobId} out of range`)
}
// Defines logging functions for demo purposes
function render(val){ console.log(`Rendering ${val}`); }
function pass(reason){ console.log(`Doing nothing (${reason})`) }
score:1
I am using this helper that allows me to have switch statements in JSX
// in helpers folder
const switchTrue = (object) => {
const { default: defaultValue, ...rest } = object;
const obj = { default: defaultValue, ...rest };
const result = Object.keys(obj).reduce((acc, cur) => {
return {
...acc,
[cur === 'default' ? 'true' : cur]: obj[cur],
};
}, {});
return result['true'];
};
const Sample = () => {
const isDataLoading = false;
return (
<div>
{
switchTrue({
[`${isDataLoading}`]: <div>Loading</div>,
[`${!isDataLoading}`]: <div>Data Ready</div>,
default: <div>Default</div>,
})
}
</div>
)
}
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>
score:1
Is easy my example in typescrip, change page on object in state
const App = (params: params) => {
const [menu, setMenu] = useState<string>("bip")
const handleOnClick = (value: string) => setMenu(value);
const pages: { [key: string]: React.ReactNode } = {
bip: <div>bip</div>,
boop: <div>Boop</div>
}
return (
<>
{pages[menu]}
<OtherComponent onClick={handleOnClick} />
</>
);
};
export default App;
score:2
Here is a full working example using a button to switch between components
you can set a constructor as following
constructor(props)
{
super(props);
this.state={
currentView: ''
}
}
then you can render components as following
render()
{
const switchView = () => {
switch(this.state.currentView)
{
case "settings": return <h2>settings</h2>;
case "dashboard": return <h2>dashboard</h2>;
default: return <h2>dashboard</h2>
}
}
return (
<div>
<button onClick={(e) => this.setState({currentView: "settings"})}>settings</button>
<button onClick={(e) => this.setState({currentView: "dashboard"})}>dashboard</button>
<div className="container">
{ switchView() }
</div>
</div>
);
}
}
As you can see I am using a button to switch between states.
score:2
I converted accepted answer to arrow functional component solution and saw James provides similar answer and one can get error not defined
. So here is the solution:
const renderSwitch = (param) => {
switch (param) {
case "foo":
return "bar";
default:
return "foo";
}
};
return (
<div>
<div></div>
{renderSwitch(param)}
<div></div>
</div>
);
score:2
I know I'm a bit late to the party, but I think this implementation might help
You can render the components using conditional operators instead
If you had the following switch statement
switch(value) {
case CASE1:
return <Case1Component/>
case CASE2:
return <Case2Component/>
case CASE3:
return <Case3Component/>
default:
return <DefaultComponent/>
}
You can convert it to react component like so
const cases = [CASE0, CASE1, CASE2]
// Reminds me of 'react-router-dom'
return (
<div>
{value === cases[0] && <Case0Component/>}
{value === cases[1] && <Case1Component/>}
{value === cases[2] && <Case2Component/>}
{!cases.includes(value) && <DefaultComponent/>}
</div>
)
score:2
This helper should do the trick.
Example Usage:
{componentSwitch(3, (switcher => switcher
.case(1, () =>
<p>It is one</p>
)
.case(2, () =>
<p>It is two</p>
)
.default(() =>
<p>It is something different</p>
)
))}
Helper:
interface SwitchCases<T> {
case: (value: T, result: () => React.ReactNode) => SwitchCases<T>;
default: (result: () => React.ReactNode) => SwitchCases<T>;
}
export function componentSwitch<T>(value: T, cases: (cases: SwitchCases<T>) => void) {
var possibleCases: { value: T, result: () => React.ReactNode }[] = [];
var defaultResult: (() => React.ReactNode) | null = null;
var getSwitchCases: () => SwitchCases<T> = () => ({
case: (value: T, result: () => React.ReactNode) => {
possibleCases.push({ value: value, result });
return getSwitchCases();
},
default: (result: () => React.ReactNode) => {
defaultResult = result;
return getSwitchCases();
},
})
// getSwitchCases is recursive and will add all possible cases to the possibleCases array and sets defaultResult.
cases(getSwitchCases());
// Check if one of the cases is met
for(const possibleCase of possibleCases) {
if (possibleCase.value === value) {
return possibleCase.result();
}
}
// Check if the default case is defined
if (defaultResult) {
// Typescript wrongly assumes that defaultResult is always null.
var fixedDefaultResult = defaultResult as (() => React.ReactNode);
return fixedDefaultResult();
}
// None of the cases were met and default was not defined.
return undefined;
}
score:3
I really liked the suggestion in https://stackoverflow.com/a/60313570/770134, so I adapted it to Typescript like so
import React, { FunctionComponent } from 'react'
import { Optional } from "typescript-optional";
const { ofNullable } = Optional
interface SwitchProps {
test: string
defaultComponent: JSX.Element
}
export const Switch: FunctionComponent<SwitchProps> = (props) => {
return ofNullable(props.children)
.map((children) => {
return ofNullable((children as JSX.Element[]).find((child) => child.props['value'] === props.test))
.orElse(props.defaultComponent)
})
.orElseThrow(() => new Error('Children are required for a switch component'))
}
const Foo = ({ value = "foo" }) => <div>foo</div>;
const Bar = ({ value = "bar" }) => <div>bar</div>;
const value = "foo";
const SwitchExample = <Switch test={value} defaultComponent={<div />}>
<Foo />
<Bar />
</Switch>;
score:3
make it easy and just use many if statements.
for example:
<Grid>
{yourVar==="val1"&&(<> your code for val1 </>)}
{yourVar==="val2"&&(<> your code for val2 </>)}
.... other statments
</Grid>
score:4
How about:
mySwitchFunction = (param) => {
switch (param) {
case 'A':
return ([
<div />,
]);
// etc...
}
}
render() {
return (
<div>
<div>
// removed for brevity
</div>
{ this.mySwitchFunction(param) }
<div>
// removed for brevity
</div>
</div>
);
}
score:4
You can't have a switch in render. The psuedo-switch approach of placing an object-literal that accesses one element isn't ideal because it causes all views to process and that can result in dependency errors of props that don't exist in that state.
Here's a nice clean way to do it that doesn't require each view to render in advance:
render () {
const viewState = this.getViewState();
return (
<div>
{viewState === ViewState.NO_RESULTS && this.renderNoResults()}
{viewState === ViewState.LIST_RESULTS && this.renderResults()}
{viewState === ViewState.SUCCESS_DONE && this.renderCompleted()}
</div>
)
If your conditions for which view state are based on more than a simple property – like multiple conditions per line, then an enum and a getViewState
function to encapsulate the conditions is a nice way to separate this conditional logic and cleanup your render.
score:4
Switch-Case statement within React Component could be used as follows:
<div id="time-list">
{
(() => {
switch (groupByFilterId) {
case 0:/*Case 0 */
return (
<div>Case 0</div>
)
break;
case 1: /*Case 1 */
return (
<div>Case 1</div>
)
break;
case 2:/*Case 2 */
return (
<div>Case 2</div>
)
break;
}
})()}
</div>
score:4
import React from 'react';
import ListView from './ListView';
import TableView from './TableView';
function DataView({
currView,
data,
onSelect,
onChangeStatus,
viewTodo,
editTodo,
deleteTodo,
}) {
return (
<div>
{(function () {
switch (currView) {
case 'table':
return (
<TableView
todos={data}
onSelect={onSelect}
onChangeStatus={onChangeStatus}
viewTodo={viewTodo}
editTodo={editTodo}
deleteTodo={deleteTodo}
/>
);
case 'list':
return (
<ListView
todos={data}
onSelect={onSelect}
onChangeStatus={onChangeStatus}
viewTodo={viewTodo}
editTodo={editTodo}
deleteTodo={deleteTodo}
/>
);
default:
break;
}
})()}
</div>
);
}
export default DataView;
score:6
Although this is yet another way to do it, if you have gone all-in on hooks, you could take advantage of useCallback
to produce a function that is only recreated when necessary.
Let's say you have a component which should be rendered according to a status
prop. With hooks, you could implement this as follows:
const MyComponent = ({ status }) => {
const renderContent = React.useCallback(() => {
switch(status) {
case 'CONNECTING':
return <p className="connecting">Connecting...</p>;
case 'CONNECTED':
return <p className="success">Connected Successfully!</p>
default:
return null;
}
}, [status]);
return (
<div className="container">
{renderContent()}
</div>
);
};
I like this because:
- It's obvious what is going on - a function is created, and then later called (the immediately invoked anonymous function method looks a little odd, and can potentially confuse newer developers)
- The
useCallback
hook ensures that therenderContent
callback is reused between renders, unless the depedencystatus
changes - The
renderContent
function uses a closure to access the necessary props passed in to the component. A separate function (like the accepted answer) requires the passing of the props into it, which can be burdensome (especially when using TypeScript, as the parameters should also be typed correctly)
score:9
You can do something like this.
<div>
{ object.map((item, index) => this.getComponent(item, index)) }
</div>
getComponent(item, index) {
switch (item.type) {
case '1':
return <Comp1/>
case '2':
return <Comp2/>
case '3':
return <Comp3 />
}
}
score:11
function Notification({ text, status }) {
return (
<div>
{(() => {
switch (status) {
case 'info':
return <Info text={text} />;
case 'warning':
return <Warning text={text} />;
case 'error':
return <Error text={text} />;
default:
return null;
}
})()}
</div>
);
}
score:22
lenkan's answer is a great solution.
<div>
{{ beep: <div>Beep</div>,
boop: <div>Boop</div>
}[greeting]}
</div>
If you need a default value, then you can even do
<div>
{{ beep: <div>Beep</div>,
boop: <div>Boop</div>
}[greeting] || <div>Hello world</div>}
</div>
Alternatively, if that doesn't read well to you, then you can do something like
<div>
{
rswitch(greeting, {
beep: <div>Beep</div>,
boop: <div>Boop</div>,
default: <div>Hello world</div>
})
}
</div>
with
function rswitch (param, cases) {
if (cases[param]) {
return cases[param]
} else {
return cases.default
}
}
score:28
A way to represent a kind of switch in a render block, using conditional operators:
{(someVar === 1 &&
<SomeContent/>)
|| (someVar === 2 &&
<SomeOtherContent />)
|| (this.props.someProp === "something" &&
<YetSomeOtherContent />)
|| (this.props.someProp === "foo" && this.props.someOtherProp === "bar" &&
<OtherContentAgain />)
||
<SomeDefaultContent />
}
It should be ensured that the conditions strictly return a boolean.
score:32
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.
score:42
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.
score:85
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>
);
}
score:222
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>
)
}
Source: stackoverflow.com
Related Query
- How to use switch statement inside a React component?
- How to use Switch case in React js functional component inside return efficiently by reusing?
- How to use AND and OR statement inside the component while comparing in react component
- how to use a CDN inside a React component
- How can one use a polymer component inside a react component ? Is it possible?
- How to use React Context inside function of Class component
- How can I use React Router's withRouter HOC inside my own higher order component (HOC)?
- React Router Switch statement with routes grouped as component inside does not go to Not Found route
- How to use a React component inside a Gatsby plugin?
- Refactoring React Class component to Functional, how to use action creator inside useEffect()
- How to use React Router Link component inside an Ant Design Tab component
- How to use Facebook Javascript SDK to login and force re-authentication with React Web and Typescript inside of a component
- How to use <webview> methods inside a react component
- How to use useState inside a react functional component which is async
- How to use if statement inside React JSX loop/map
- How can i use a jquery/html/css component inside my react page
- Is that possible to use switch statement inside a constructor in react js
- How to use data of an Async function inside a functional component to render HTML in React
- How to call react component in conditional statement inside another component
- How to use children with React Stateless Functional Component in TypeScript?
- How to use an array as option for react select component
- Making an HTML string from a React component in background, how to use the string by dangerouslySetInnerHTML in another React component
- How to pass props to component inside a React Navigation navigator?
- Unable to use Arrow functions inside React component class
- How to mock a custom hook inside of a React component you want to test?
- How to use switch cases inside JSX: ReactJS
- how to load React app / Lib inside ExtJs Component
- How to use material-ui IconMenu inside cell of React fixed-data-table
- How to use FormattedMessage inside an option tag in React 0.14?
- How to use Media Queries inside a React Styled Components Keyframe?
More Query from same tag
- Redux ToolKit Query - Make multiple queries in the same component dependant on each other
- react-checkbox-tree doesn't expand
- Unable to update the state when button inside table cell clicked , React Ant Design
- React/FireStore : Error: Objects are not valid as a React child
- ReactJS sluggish with frequent updates to big DOM?
- ReactJS: How to access an array of form input children?
- React State data not able to be passed as props
- PDF file sent from flask to client is empty when downloaded
- How to call a onclick function inside a Template literal in React js
- How to declare useMutation return type in 'react-query'
- How to avoid returning undefined if condition is not met
- Render a nested array of objects in react
- react-select don't show keyboard on mobile devices and prevent zoom
- How do I mock a promise in reactjs?
- Is React Router causing my component to render twice?
- mapping items and flattening into single array in reactjs
- React / Stripe / createPortalLink() with firebase v9
- How to align items in material-ui App Bar?
- I want to handle error state in Form.Item Ant design. how to handle disable button?
- How can I make useEffect() optional based on props
- navbar from Bootstrap to reactjs
- How to set default value in referenceinput in react - admin
- Material-UI datepicker invalid date format issue
- How to detect 404 routes (NoMatch) when doing SSR with "react-router-dom" without using <Redirect>?
- How can you display an specific number of rendering after mapping a json object?
- Update nested state in reducer
- Pass to this.state my rows and their json schema
- React setState doesn't update boolean variable
- ReactNative - Tapping row in ListView gives error: Cannot read property `_pressRow` of null
- How to fix the Argument of type 'Date[]' is not assignable to parameter of type '(prevState: undefined) in react