React Vocabulary 101

React Vocabulary 101

Demystifying terminologies you may have heard but never understood.

In this article, I want to go over terms in React that you may have heard but never fully understood. I hope this shines some clarity and helps you better learn and understand React as you hear these terms.

Render phase

React breaks up the work it has to do to render your app into two phases, the render and commit phase.

During the render phase React executes all of your components and gets a JSX tree as a result. If it is the first time React renders your app, it will just return the entire JSX tree.

Screenshot from 2022-09-17 15-55-19.png

If it is a re-render (update) React is going to get the new JSX tree and compare it with the old one and compute a diff. This is called reconciliation.

Screenshot from 2022-09-17 16-00-18.png

Commit phase

The second phase of rendering is called the commit phase. Once React has the diff, it can begin the process of updating the DOM. React will update the current DOM to match the diff.

Screenshot from 2022-09-17 16-29-23.png

State

State is runtime data that React relies upon in order to render your app. This data changes over time and usually affects the output of our app. There are other states that isn't React state which changes over time but doesn't trigger re-renders nor live inside React, like our scroll position, mouse position, etc.

React gives us APIs to define states like useState for an instance.

import { useState } from 'react'

export function Counter() {
  const [count, setCount] = useState(0)

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount((previousState) => previousState + 1)}>
        Increment
      </button>
    </div>
  )
}

Side effects

Any other code in our component that is not directly related to creating or manipulating JSX, can be considered side effects.

For an instance, fetching or console logging.

import { useState } from 'react'

export function Counter() {
  const [count, setCount] = useState(0)

  useEffect(() => {
    fetch('...')
    console.log('hi')
  }, [])

  return (
    <div>
      <p>Count: {count}</p>
      <button onClick={() => setCount((previousState) => previousState + 1)}>
        Increment
      </button>
    </div>
  )
}

Purity

Render functions should be pure.

A pure function is a function that has no side effects, and whose output depends solely on its input.

We can not have side effects inside the render function, because, given the same props and state, it will return a different result, leading to unnecessary re-renders.

An example is if we were to use new Date() inside of the function, every time we re-render it, it is gonna return a different result because of the date function.

export function Sample() {
  const currentDate = new Date() // impure

  return (
    <div>
      <p>{currentDate}</p>
    </div>
  )
}

Idempotence

A function is idempotent when no matter how many times you call it, you will still achieve the same result. No matter how many times you call it, its side effects have the same effect on the overall system state.

In React, we want to make sure that our side effects are idempotent. This is why useEffect gives us a clean-up function, a function that runs when the component unmounts (gets removed from the page).

Let's say we are setting up a subscription for an instance.

import { useEffect } from 'react'

export function Sample() {
  function handleNotification() {
    // ...
  }

  useEffect(() => {
    socket.addEventListener('notification', handleNotification)

    // This is the clean-up function
    return () => {
      socket.removeEventListener('notification', handleNotification)
    }
  }, [notifications])

  //   ...
}

React can mount and unmount the Sample component numerous times, but that won't affect the overall system, we won't end up with multiple subscriptions because React has mounted and unmounted the component.

This is one of the big mistakes I see beginners especially do in React, forgetting to implement the clean-up function. It often leads to subtle bugs that are hard to pin down.

Conclusion

I hope this helped!

Terminologies can sometimes be confusing, which is why I wrote this honestly, for myself.