How to Avoid Default Props Render Trap in React

rhuzaifa

Huzaifa Rasheed

Posted on February 20, 2022

How to Avoid Default Props Render Trap in React

What is it?

Let's say we have a component with a default prop like this



import React, { useEffect, useState } from "react";

const RerenderChild = ({ value = [] }) => {
  const [valueFromProp, setValueFromProp] = useState([]);

  useEffect(() => {
    setValueFromProp(value);
  }, [value]);

  return (
    <div>
     {/* ...component */}
    </div>
  );
};

export default RerenderChild;


Enter fullscreen mode Exit fullscreen mode

Whenever the value prop is nullish (not set by the calling component), the useEffect causes the component to render infinitely. This is the Default Props Render Trap. We get something like this in the browser console.
Infinite Re-rendering in React Component

Why It Happens

When we don't provide the value for the value prop it takes the default value provided as argument, which in our case is []. This triggers the useEffect hook which updates the valueFromProp state. The state change causes the component to re-render.

Now when the component re-renders, it takes the new prop values which again are the default one's. This again triggers the useEffect and the whole cycle repeats. That's why we end up with an infinite loop.

The Solution

We have to make the default prop values a part of our component definition. We can do that in these ways.

1. Use defaultProps property.

We can set the default props value by using the component's defaultProps property. Our component now becomes



import React, { useEffect, useState } from "react";

const RerenderChild = ({ value }) => {
  const [valueFromProp, setValueFromProp] = useState([]);

  useEffect(() => {
    setValueFromProp(value);
  }, [value]);

  return (
    <div>
      {/* ...component */}
    </div>
  );
};

RerenderChild.defaultProps = {
  value: [],
};

export default RerenderChild;


Enter fullscreen mode Exit fullscreen mode

2. Declare default props as constants.

We can declare constants outside of our component and set them as our default prop value.



import React, { useEffect, useState } from "react";

const DEFAULT_VALUE = [];

const RerenderChild = ({ value = DEFAULT_VALUE }) => {
  const [valueFromProp, setValueFromProp] = useState([]);

  useEffect(() => {
    setValueFromProp(value);
  }, [value]);

  return (
    <div>
      {/* ...component */}
    </div>
  );
};

export default RerenderChild;


Enter fullscreen mode Exit fullscreen mode

Hope this helps you to avoid the infinite loop. Thanks 😊.

πŸ’– πŸ’ͺ πŸ™… 🚩
rhuzaifa
Huzaifa Rasheed

Posted on February 20, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related