Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to use React.memo with a Component contains children

I have two Components, and I wrapped Parent with React.memo:

Child

const Child = ()=> <div>I'm Child</div>

export default Child

Parent

const Parent = (props)=> <div>{props.children}</div>

export default React.memo(Parent)

Use in App:

const App = () => {
  const [count, setCount] = useState(0)

  return(
    <div>
      <button onClick={()=>setCount(count+1)}></button>

      <Parent>
        <Child></Child>
      </Parent>
    </div>
  )
}

Click the button, result:

The Parent Component will rerender, so the memo not working because it's children is a function component

So, how can I prevent rerender?

I know a way to solve by useMemo, but it's ugly and not friendly, do you have better ideas?

const App = () => {
  const [count, setCount] = useState(0)

  const children = useMemo(()=><Child></Child>,[])

  return(
    <div>
      <button onClick={()=>setCount(count+1)}></button>

      <Parent>
        {children}
      </Parent>
    </div>
  )
}
like image 218
Yokiijay Avatar asked Mar 13 '20 11:03

Yokiijay


People also ask

Can React components have children?

You can use props. children in React in order to access and utilize what you put inside the open and closing tags when you are creating an instance of a component.

Why using the children prop makes React memo not work?

It's an obvious issue in retrospect: React. memo() shallowly compares the new and the old props and short-circuits the render lifecycle if they're the same, and the children prop isn't special, so passing newly created React elements (so any JSX that isn't specifically persisted) as children will cause a re-render.

How do you access the child of a React component?

In React we can access the child's state using Refs. we will assign a Refs for the child component in the parent component. then using Refs we can access the child's state. Creating Refs Refs are created using React.

Does React memo work with objects?

By default, React. memo() performs a shallow comparison of props and prop objects. We can then pass this function as a second argument in React.


1 Answers

const children = useMemo(()=><Child></Child>,[])

Is the easiest way to go. Using memo(Child) wont work since jsx in fact returns a new object whenever you call <Child />. React.memo by default just use simple shallow comparison so there really is no other direct way to solve it. You can create your own function that would eventually support children and pass it to React.memo(MyComp, myChildrenAwareEqual).

like image 83
Maxime Bret Avatar answered Oct 27 '22 03:10

Maxime Bret