Search code examples
javascriptreactjsreduxreact-reduxreact-hooks

How to memoize useSelector value so that re render is prevented on any state change in the component?


I am using callback to memoize part of component which uses useSelector value. But another state variable is changing withing the component as I am taking input, which is triggering another re render of comp, thereby useselector is getting called again and re rendering the part where I have used useCallback as selector value is there as a dependency. How can I memorize useSelector value so that any state change change within the component does not trigger selector update unless dispatch gets called somewhere and updates the state.

const chat = useSelector((state: any) => state.user.rooms[index]) 
const [message, setMessage] = useState("");

chat is the selector value and message is the state for input tag.

const Component = useCallback(() => {
    return (
      <div className="h-[75%] bg-yellow-200 relative overflow-y-scroll flex  flex-col">
        {chat?.messages.map((message: any, index: number) => {
          console.log(message.sentBy._id, userId);
          let sentByme = message.sentBy._id === userId;
          return (
            <div className={"w-[50%] min-h-[20%]  border-4  rounded-3xl "}>
              <p>{message.text}</p>
              <p>
                {message.timeStamp} : {sentByme ? "me" : message.sentBy.name}
              </p>
            </div>
          );
        })}
      </div>
    );
  }, [chat]);

I decided to set aside chat selector value inside of useCallback to prevent re render on input state change ie "message" but re rendering is happening


Solution

  • Components rerender as a whole, and per default all their children will re-render after that as well. If you want a part of your component not to rerender, you need to split that into two components and render them side-by-side or wrap the child component in React.memo.

    Selectors will be executed on each render and also on every Redux dispatch - if that is a performance problem at some point, look into memoized selectors. https://redux.js.org/recipes/computing-derived-data

    In your case the selector itself is not a performance problem at all though.