Dynamic Rendering in React
Often times we will want to render different elements or components conditionally.
Imagine a login button. The user will see the login button until they login. Then they will see a log out button. Maybe an help message should be rendered until the clicks to exit it. Or you want to display a loading icon until you receive your data.
This is called Dynamic Rendering
.
React has many ways to render items dynamically. The general concept in pseudo code is:
if [a certain condition is met]
<Render something/>
else
<Render something else instead/>
if-else
Consider the following component:
export default function App(){
return(
<div>
<h1>Hello</h1>
<h1>Good Bye</h1>
</div>
)
}
We only want to render one h1
or the other. We could do return one block of JSX, or the other:
export default function App(props){
if(props.phrase === "greeting"){
return(
<h1>Hello</h1>
)
} else {
return(
<h1>Good Bye</h1>
)
}
}
Ternary
It would be cooler (and much more readable) if we could use one return statement and one block of JSX. Since if-else statements don't play nice with JSX, we'll use a [ternary](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Conditional_Operator):
export default function App(props){
return(
<div>
{ props.phrase === "greeting"
? <h1>Hello</h1>
: <h1>Good Bye</h1>
}
</div>
)
}
Since we're writing JavaScript, we need to open our statement with some curly brackets {
. We write our condition (something that will evaluate to true or false), a ?
to put what to render if true, and all our else
stuff after the :
.
Sometimes we don't have an else. We still need something if writing a ternary. null
is the common options.
export default function App(props){
return(
<div>
{ props.phrase === "greeting"
? <h1>Hello</h1>
: null
}
</div>
)
}
Ampersand (&&)
We can do better though. Better that throwing in that unsightly `null`. We will use the `&&`.
true && <h1>Hello</h1>
always evaluates to ‘Hello World’. A false && <h1>Hello</h1>
always evaluates to false and React ignores and skips the expression. It doesn't get rendered!!
export default function App(props){
return(
<div>
{ props.phrase === "greeting" && <h1>Hello</h1> }
</div>
)
}
Using these principles, you can do a lot of cool things. Could you figure out how to use a switch statement to render one of five phrases?
Switch
We can't use a switch right in the JSX.
We could use a switch to determine which block of JSX a renderable JavaScript variable could be assigned to.
export default function App(props){
let phraseJSX
switch(props.phrase) {
case 'greeting':
return phraseJSX = <h1>Hello</h1>
case 'question':
return phraseJSX = <h1>What's up?</h1>
case 'farewell':
return phraseJSX = <h1>Good Bye</h1>
default:
return null
}
return(
<div>
{phraseJSX}
</div>
)
}
You're also allowing to throw in a self invoking function in there, but you'll have to decide which is most readable.
export default function App(props){
return(
{(() => {
switch(props.phrase) {
case 'greeting':
return <h1>Hello</h1>
case 'question':
return <h1>What's up?</h1>
case 'farewell':
return <h1>Good Bye</h1>
default:
return null
}
})()}
}
)
}
This should give you a good enough start. Try using a few of these to improve your users experience!