Search code examples
javascriptreactjsreduxreselect

React-Redux select value without re-rendering


I'm using react-redux with reselect.

Any API call is performed in its own component when its store's "status" is changed to "Pending". The API component immediately changes that status to "Accepted" (and then a few more relevant status as it makes the async call).

The number of results to return can change on several factors, but I don't want to rerender the component if the status is not "Pending".

I could just have an if (!isPending) return, but I would rather depend on the selectors entirely.

I came up with:

const selectCount = createSelector(
  [selectStatus, selectCount],
  (status, count) => status === 'Pending' && count
)

I'm pretty sure this will work with an extra condition, but is there a better way?


Solution

  • In your case, if selectStatus and selectCount are the input selectors, the createSelector will recalculate the result when either of them changes. If you only want to recalculate when the status is "Pending," you may want to use a simple memoization technique for the count.

    I mean something like this, using useMemo:

    import { useMemo } from 'react';
    import { createSelector } from 'reselect';
    
    const ExampleComponent = ({ selectStatus, selectCount }) => {
      const count = useMemo(() => {
        const status = selectStatus();
        const count = selectCount();
    
        return status === 'Pending' ? count : null;
      }, [selectStatus, selectCount]);
    
    
      if (!count) {
        return null; // anyother condition to skip rendering
      }
    
      return (
        <div>
          {/* Render with the 'count' */}
        </div>
      );
    };
    
    export default ExampleComponent;

    So in this way, the count value will only be recalculated when either selectStatus or selectCount changes, and it will only be non-null when the status is "Pending." This approach ensures that unnecessary re-renders are avoided when the status is not "Pending.".

    I hope this gives answer to your question.