easyReact#39

Conditional rendering

Prompt

Render a welcome message if the user is logged in, otherwise show a login prompt. Use a "loggedIn" state variable and a button to toggle it. Use a ternary for the conditional.

Solution

export default function Welcome() {
  const [loggedIn, setLoggedIn] = useState(false)
  return (
    <View>
      {loggedIn ? <Text>Welcome back!</Text> : <Text>Please log in</Text>}
      <Button title={loggedIn ? 'Log Out' : 'Log In'} onPress={() => setLoggedIn(l => !l)} />
    </View>
  )
}
Mentor's take

Conditional rendering exists because JSX is just expressions — there is no template directive like v-if; you branch with plain JavaScript, and the reconciler handles mounting and unmounting whatever the expression evaluates to. The ternary is the workhorse: both branches are visible in one place, and each branch produces a real element the diff can compare.

The mechanics here: loggedIn lives in state because it drives the UI — flipping it re-renders, and React swaps the <Text> subtree. The toggle uses the functional updater (setLoggedIn(l => !l)) because the next state depends on the previous one; reading the closed-over loggedIn works today but breaks the moment two toggles batch into one render.

Know the && trap: {count && <Badge />} renders the literal 0 when count is zero — and in React Native, a bare string or number outside a <Text> throws. Coerce (count > 0 &&) or use a ternary with an explicit null.

Red flag: Juniors say "setState is asynchronous" when asked why the toggle needs an updater function. The precise answer is batching — the state variable is a closure constant for the render, and functional updaters read the queued value, not the stale one.

Say it: "Conditional rendering is just expression evaluation — I use ternaries for two-branch UI, guard && against falsy-zero rendering, and functional updaters whenever next state depends on previous."