Simple trick to optimize React

Apr 9, 2022

When using React, efficient rendering is crucial for large scale applications to maintain performance. I'm going to show simple technique to optimize rendering by using the children prop and without the need of using useCallback, useMemo, or memo

To demonstrate the problem, I've created a recursive function to calculate the fibonacci sequence and a ChildComponent that return value of the function. This component will be used in both examples below with different values passed in.

export default function Page() {
  return (
    <div>
      <ParentComponent n={1}/>
      <ParentComponent n={36}/>
    </div>
  )
}
 
const ParentComponent = ({ n }: { n: number }) => {
  const [count, setCount] = useState(1)
  return (
    <div>
      <h1>Count: {count}</h1>
      <button onClick={() => setCount(count + 1)}>Increment</button>
      <ChildComponent n={n} />
    </div>
  )
}
const fibonacci = (n: number): number => {
  if (n <= 1) return n
  return fibonacci(n - 1) + fibonacci(n - 2)
}
 
const ChildComponent = ({ n }: { n: number }) => {
  const fib = fibonacci(n)
  return (
    <div>
      <h1>{`fibonacci(${n})`}</h1>
      <p>Fibonacci number: {fib}</p>
    </div>
  )
}

Try clicking the increment buttons below to see if you notice anything.

Count: 1

ChildComponent

fibonacci(1)

Fibonacci number: 1

Count: 1

ChildComponent

fibonacci(36)

Fibonacci number: 14930352

You should immediately noticed that the count value on the right isn't updating its value as quickly as the one on the left.

Why this happens

The state count "lags" between each button click because React re-renders every time count changes. This includes the rendering of the ChildComponent, causing unnecessary re-renders.

The optimization

To fix this, we can update the props and replace the direct rendering of ChildComponent with the children prop. By doing this, we pass ChildComponent as children instead of rendering it inside the parent directly.

Why this works

In React, components passed as children do not automatically re-render when the parent component updates its state.

Final Demo

Count: 1

ChildComponent

fibonacci(1)

Fibonacci number: 1

Count: 1

ChildComponent

fibonacci(36)

Fibonacci number: 14930352