DEV Community

Sol Lee
Sol Lee

Posted on

Why Should We Avoid `object` Props in React

Summary

  • In react, passing object to props triggers rerendering (we need to use useMemo to avoid this)
  • If possible, pass primitive values to props
  • Divide the component that is passing too many props into several smaller components

How React detects changes in props

React uses the so-called "shallow comparison" to detect any changes in the props and states. Specifically, it is known that the javascript syntax Object.is() is used for the comparison. Then, guess what the following code will result:

Object.is(
  { hello: "world },
  { hello: "world },
)
Enter fullscreen mode Exit fullscreen mode

The answer is... false!

Both look the same. However, javascript objects are passed by reference, meaning that even if they look the same, they are not the same: they have different allocations in the memory.

Having said that, the Child component below will be rerendered even if it is memoized:

const Parent = () => {
  const user = { name: "Lee", age: 30 };

  return <Child user={user} />;
};

// Child gets rerendered
const Child = React.memo(({ user }: { user: { name: string; age: number } }) => {
  console.log("Child 렌더링");
  return <div>{user.name}</div>;
});
Enter fullscreen mode Exit fullscreen mode

We may avoid unnecessary rerendering by using the appropriate react hook: useMemo

const Parent = () => {
  const user = React.useMemo(() => ({ name: "Lee", age: 30 }), []);

  return <Child user={user} />;
};
Enter fullscreen mode Exit fullscreen mode

However, it is known that both useMemo and useCallback are recommended to be used for "expensive" calculations. In our example, an object with only two keys and string values is not that expensive. We need another solution.

Pass primitive values as props

If possible, it is better to pass the primitive values as props. For example:

const Parent = () => {
  const user = { name: "Lee", age: 30 };

  return <Child name={user.name} age={user.age} />;
};
Enter fullscreen mode Exit fullscreen mode

In this case it wasn't a laborious task to pass each key to Child's props. However, sometimes we need to deal with huge objects with more than 10 key-values.

Create another component (single resposibility principle)

If we stick to the SOLID principles, we may think about creating several smaller components that deal with each prop. Or, at least, distribute the object's key-values to several components.

const Parent = () => {
  const user = { name: "Lee", age: 30 };

  return (
    <>
      <Child1 name={user.name} />
      <Child2 age={user.age} />
    </>
  )
};
Enter fullscreen mode Exit fullscreen mode

Top comments (0)