Wyatt
Wyatt

Reputation: 73

Prevent `useSelector` from re-rendering component?

I have a table with thousands of rows.

import React from "react"
import { useSelector } from "react-redux";
import { useEffect } from "react";
import Source from "../components/TranslationTable/Source";

const SourceContainer = React.memo((props) => {

  const suggestionArray = useSelector((state) => state.suggestions.suggestionArray );
  const isFetching = useSelector((state) => state.suggestions.isFetching);

  let source = props.source;

  if (props.shouldHighlight && !isFetching) {
     //I will have code here to highlight text at some point
  }


  return (
    <Source source={source}>{console.log("rendered")}</Source>
  )
}, (prevProps, nextProps) => {
  return true;
});

export default SourceContainer;

The above component is located inside the first column of each row. When the row is selected, props.shouldHighlight becomes true.

The problem that I have is that every single SourceContainer component re-renders every time a row is focused. When a row gets focused, isFetching becomes true in the redux state, and suggestionArray will become equal to an array of suggestions based upon the data in the selected row.

If I remove the if statement and the suggestionArray variable, the component STILL re-renders. Meaning, the only thing required to re-produce this issue is having an unused useSelector variable (ifFetching).

Can anyone explain how I can use useSelector without re-rendering the component when the state value of that selector changes?

Upvotes: 3

Views: 8327

Answers (1)

Matthieu Bouxin
Matthieu Bouxin

Reputation: 127

Using useSelector, you add a dependency to your Component and it is normal that it re-renders if the content of useSelector changes.

The trick here is to make a less varying content for your useSelector function. Or at least something that changes only if the component needs to re-render

For exemple, from what I understand of what you are trying to achieve, your component should only change if "props.shouldHighlight && !isFetching" changes value.

If that's the case, then what you want to do is this :

const isFetching = useSelector((state) => (!state.suggestions.isFetching && props.shouldHighlight));

Upvotes: 4

Related Questions