简体   繁体   中英

Is there a way to force a re-render of a child component from the parent component without using changing its props in React?

The problem

I have a parent (X) component that manages a lot of states and children components.

Among these children, I have an animated component (Y) (it is an avatar that has different faces and changes faces in sync with what he says).

For now, the type of face is a state in X and is given as a prop to Y. This mechanism is done by setting a list of timers which will change the state at the required times. I need to have the logic of types of faces inside X because I deal with the speech of the avatar inside X.

The problem is that, when speaking, the avatar changes faces very frequently, causing too frequent re-renders of all the children.

The things that I had tried so far

  1. One solution that I tried was to wrap the other children in React.memo() to avoid the excessive re-renders.

    In that case, I have a problem:

    One of the children (Z) is wrapping a button that causes the avatar to speak, using as onClick() function the sayText() function given from X as a prop. For Z, using React.memo() is not sufficient. Indeed, when I use React Profiler, I see that Z still re-renders each time the parent re-renders because it says that the sayText() prop changes. For this, a solution could be to implement a custom props check for the React.memo() but since sayText() is dependent on other states (the appearance of the avatar, its voice etc...), I can't just memoize it once.

  2. The alternative I thought about was: I could avoid having the type of face as a state but just force a re-render of a Y from X by giving it the new type of face. But I don't know if it is possible and it does not seem like a good idea any way. Anyway, does somebody know if it is possible?

Or can somebody give me advices on how to organize this better to avoid the initial problem?

I can give more details if you need in comments.

One idea is to move all the non-speech/avater children (and associated state) outside of X into Z (a new parent component).

Z renders X and all of X's old children, and X renders just the speech/avater related stuff.

sayText

Wrap the above function in useCallback , then if you used React.memo on child component Z , it should not re-render anymore because the returned callback will be the same if its dependencies don't change.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM