proxy-memoize: React Redux example doesn't seem to make sense in a real-world context

Hi there, I’m trying to understand this example:

import { useSelector } from 'react-redux';

const getScore = memoize(state => ({
  score: heavyComputation(state.a + state.b),
  createdAt: Date.now(),
}));

const Component = ({ id }) => {
  const { score, title } = useSelector(useCallback(memoize(state => ({
    score: getScore(state),
    title: state.titles[id],
  })), [id]));
  return <div>{score.score} {score.createdAt} {title}</div>;
};

I realize the example is more about how this library can interoperate with React Redux than about giving a practical scenario, but it doesn’t really help me to understand how you would use proxy-memoize to create create a memoized calculation based on both the Redux store’s state and the component’s props. The way it’s written above, useCallback will simply tear down and rebuild the memoized function whenever id changes, so there will be never any opportunity to hit the cache in this scenario.

A simpler and more efficient way of formulating the above is this:

const Component = ({ id }) => {
  const score = useSelector(getScore);
  const title = useSelector(state => state.titles[id]);
  return <div>{score.score} {score.createdAt} {title}</div>;
};

If you were trying to actually calculate expensive derived data based on both state and props with this library, how are you supposed you do it?

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 1
  • Comments: 19 (9 by maintainers)

Most upvoted comments

I assume this issue is not very active now. While the issue is not solved, let’s continue with new issues. Just created two:

Please feel free to open new issues for questions and suggestions.

Yes, I think I would be up for this! I may spend a bit of time trying proxy-memoize in my project first to make sure I better understand how to use it idiomatically. It’s been a while since I’ve used reselect myself.

Assuming highlighting applies to the HTML output, not markdown source. (because otherwise, the expensive work needs to be done every time hightlighting changes.)

const getHTML = memoize((markdown) => expensiveWork(markdown));

const getHighlightedHTML = memoize(([state, props]) => {
  const html = getHTML(state.markdown); // only re-evaluated when state.markdown changes
  return highlightHTML(html, props.highlightKeyword);
});

So, we solve this kind of use cases by nesting memoize. useCallback is just a way to follow this pattern.