Skip to content

Commit ea7a906

Browse files
committed
➕ Conditions
1 parent 0f747fc commit ea7a906

File tree

5 files changed

+214
-0
lines changed

5 files changed

+214
-0
lines changed
Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
---
2+
id: conditional-rendering-with-enum
3+
sidebar_label: Conditional rendering with enum
4+
title: Conditional Rendering with Enum
5+
description: Conditional rendering with enum | React Patterns, techniques, tips and tricks in development for Ract developer.
6+
keywords: ['conditional rendering with enum', 'child component', 'reactpatterns', 'react patterns', 'reactjspatterns', 'reactjs patterns', 'react', 'reactjs', 'react techniques', 'react tips and tricks']
7+
version: Conditional rendering with enum
8+
image: /img/reactpatterns-cover.png
9+
---
10+
11+
In JavaScript an object can be used as an enum when the object is used as a map of key value pairs.
12+
13+
```jsx
14+
const ENUM = {
15+
a: '1',
16+
b: '2',
17+
c: '3',
18+
}
19+
```
20+
21+
An enum is a great way to have multiple conditional renderings. Let's consider the notification component again, this time we can use the enum as inlined object.
22+
23+
```jsx
24+
function Notification({ text, state }) {
25+
return (
26+
<div>
27+
{{
28+
info: <Info text={text} />,
29+
warning: <Warning text={text} />,
30+
error: <Error text={text} />,
31+
}[state]}
32+
</div>
33+
)
34+
}
35+
```
36+
37+
The state property key helps us to retrieve the value from the object. It is much more readable compared to the switch case operator.
38+
39+
In this case we had to use an inlined object, because the values of the object depend on the `text` property. That would be my recommended way anyway. However, if it wouldn't depend on the text property, you could use an external static enum too.
40+
41+
```jsx
42+
const NOTIFICATION_STATES = {
43+
info: <Info />,
44+
warning: <Warning />,
45+
error: <Error />,
46+
}
47+
48+
function Notification({ state }) {
49+
return (
50+
<div>
51+
{NOTIFICATION_STATES[state]}
52+
</div>
53+
)
54+
}
55+
```
56+
57+
Although we could use a function to retrieve the value, if we would depend on the `text` property.
58+
59+
```jsx
60+
const getSpecificNotification = (text) => ({
61+
info: <Info text={text} />,
62+
warning: <Warning text={text} />,
63+
error: <Error text={text} />,
64+
})
65+
66+
function Notification({ state, text }) {
67+
return (
68+
<div>
69+
{getSpecificNotification(text)[state]}
70+
</div>
71+
)
72+
}
73+
```
74+
75+
After all, the enum approach in comparison to the switch case statement is more readable. Objects as enum open up plenty of options to have multiple conditional renderings. Consider this last example to see what is possible.
76+
77+
```jsx
78+
function FooBarOrFooOrBar({ isFoo, isBar }) {
79+
const key = `${isFoo}-${isBar}`
80+
return (
81+
<div>
82+
{{
83+
['true-true']: <FooBar />,
84+
['true-false']: <Foo />,
85+
['false-true']: <Bar />,
86+
['false-false']: null,
87+
}[key]}
88+
</div>
89+
)
90+
}
91+
92+
FooBarOrFooOrBar.propTypes = {
93+
isFoo: React.PropTypes.boolean.isRequired,
94+
isBar: React.PropTypes.boolean.isRequired,
95+
}
96+
```
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
---
2+
id: conditional-rendering-with-enum
3+
sidebar_label: Conditional rendering with enum
4+
title: Conditional Rendering with Enum
5+
description: Conditional rendering with enum | React Patterns, techniques, tips and tricks in development for Ract developer.
6+
keywords: ['conditional rendering with enum', 'child component', 'reactpatterns', 'react patterns', 'reactjspatterns', 'reactjs patterns', 'react', 'reactjs', 'react techniques', 'react tips and tricks']
7+
version: Conditional rendering with enum
8+
image: /img/reactpatterns-cover.png
9+
---
10+
11+
Last but not least there exist external solutions to deal with conditional renderings. They add control components to enable conditional renderings without JavaScript in JSX. Then it is not question anymore on how to use if else in React.
12+
13+
```jsx
14+
<Choose>
15+
<When condition={isLoading}>
16+
<div><p>Loading...</p></div>
17+
</When>
18+
<Otherwise>
19+
<div>{list.map(item => <ListItem item={item} />)}</div>
20+
</Otherwise>
21+
</Choose>
22+
```
23+
24+
Some people use it, personally I wouldn’t recommend it, JSX allows you to use the powerful set of JavaScript functionalities to handle conditional rendering, there is no need to add templating components to enable conditional rendering, a lot of people consider React including JSX as their library of choice, because they can handle the rendering with pure HTML and JS in JSX.
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
---
2+
id: multi-level-conditional-rendering
3+
sidebar_label: Multi-level conditional rendering
4+
title: Multi-level Conditional Rendering
5+
description: Multi-level conditional rendering, techniques, tips and tricks in development for Ract developer.
6+
keywords: ['multi-level conditional rendering', 'reactpatterns', 'react patterns', 'reactjspatterns', 'reactjs patterns', 'react', 'reactjs', 'react techniques', 'react tips and tricks']
7+
version: Multi-level conditional rendering
8+
image: /img/reactpatterns-cover.png
9+
---
10+
11+
What about nested conditional renderings? Let's have a look at the `List` component that can either show a list, an empty text or nothing.
12+
13+
```jsx
14+
function List({ list }) {
15+
const isNull = !list
16+
const isEmpty = !isNull && !list.length
17+
18+
return (
19+
<div>
20+
{ isNull
21+
? null
22+
: ( isEmpty
23+
? <p>Sorry, the list is empty.</p>
24+
: <div>{list.map(item => <ListItem item={item} />)}</div>
25+
)
26+
}
27+
</div>
28+
)
29+
}
30+
31+
// usage
32+
<List list={null} /> // <div></div>
33+
<List list={[]} /> // <div><p>Sorry, the list is empty.</p></div>
34+
<List list={['a', 'b', 'c']} /> // <div><div>a</div><div>b</div><div>c</div><div>
35+
```
36+
37+
It works, however I would recommend to keep the nested conditional renderings to a minimum, it makes it less readable, my recommendation would be to split it up into smaller components which themselves have conditional renderings.
38+
39+
```jsx
40+
function List({ list }) {
41+
const isList = list && list.length
42+
43+
return (
44+
<div>
45+
{ isList
46+
? <div>{list.map(item => <ListItem item={item} />)}</div>
47+
: <NoList isNull={!list} isEmpty={list && !list.length} />
48+
}
49+
</div>
50+
)
51+
}
52+
53+
function NoList({ isNull, isEmpty }) {
54+
return (!isNull && isEmpty) && <p>Sorry, the list is empty.</p>
55+
}
56+
```
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
---
2+
id: with-higher-order-component
3+
sidebar_label: With higher order component
4+
title: With Higher Order Component
5+
description: With higher order component | React Patterns, techniques, tips and tricks in development for Ract developer.
6+
keywords: ['with higher order component', 'react ternary operation', 'reactpatterns', 'react patterns', 'reactjspatterns', 'reactjs patterns', 'react', 'reactjs', 'react techniques', 'react tips and tricks']
7+
version: With higher order component
8+
image: /img/reactpatterns-cover.png
9+
---
10+
11+
Higher order component is a perfect match for conditional rendering in React. HOC can have multiple use cases. Yet one use case could be to alter the look of a component. To make the use case more specific, it could be to apply a conditional rendering for a component, let's have a look at a HOC that either shows a loading indicator or a desired component.
12+
13+
```js
14+
// HOC declaration
15+
function withLoadingIndicator(Component) {
16+
return function EnhancedComponent({ isLoading, ...props }) {
17+
if (!isLoading) {
18+
return <Component { ...props } />
19+
}
20+
21+
return <div><p>Loading...</p></div>
22+
}
23+
}
24+
25+
// Usage
26+
const ListWithLoadingIndicator = withLoadingIndicator(List)
27+
28+
<ListWithLoadingIndicator
29+
isLoading={props.isLoading}
30+
list={props.list}
31+
/>
32+
```
33+
34+
In the example above, the `List` component can focus on rendering the list. It doesn't have to bother with a loading state. Ultimately you could add more HOC to shield away multiple conditional rendering edge cases.

sidebars.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,10 @@ module.exports = {
1919
'ternary-operation',
2020
'logical-and-operator',
2121
'switch-case-operator',
22+
'conditional-rendering-with-enum',
23+
'multi-level-conditional-rendering',
24+
'with-higher-order-component',
25+
'external-templating-component',
2226
],
2327
},
2428
],

0 commit comments

Comments
 (0)