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!