Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Benefit? #2

Closed
danstiner opened this issue Sep 29, 2021 · 3 comments · Fixed by #3
Closed

Benefit? #2

danstiner opened this issue Sep 29, 2021 · 3 comments · Fixed by #3
Labels
documentation Improvements or additions to documentation

Comments

@danstiner
Copy link
Contributor

danstiner commented Sep 29, 2021

Curious, is there a benefit to useSelectorWith like the following:

import { useSelectorWith } from 'use-selector-with';

const selectFruit = (state, name) => state.fruits[name];

const MyComponent = () => {
  const apple = useSelectorWith(selectFruit, 'apple');

  // ...
};

versus just using useSelector?

import { shallowEqual, useSelector } from 'react-redux';

const selectFruit = (state, name) => state.fruits[name];

const MyComponent = () => {
  const apple = useSelector(state => selectFruit(state, 'apple'), shallowEquals);

  // ...
};

Performance wise I think the useSelector version would be actually a smidge faster and I don't see any other relevant differences but I could be missing something!

Busy this week but sometime I'll try to do a microbenchmark. The useCallback inside useSelectorWith adds some overhead, probably more than memoizing the selector function would gain, except for maybe very very complex selectors. Fun reading, react perf is tricky: https://kentcdodds.com/blog/usememo-and-usecallback

@danstiner danstiner changed the title Performance benefit? Benefit? Sep 29, 2021
@danstiner
Copy link
Contributor Author

danstiner commented Sep 29, 2021

Oh I see, this is handy with reselect selector creators. Basically instead of the following from https://react-redux.js.org/api/hooks#using-memoizing-selectors:

export const CompletedTodosCount = ({ completed }) => {
  const selectCompletedTodosCount = useMemo(makeSelectCompletedTodosCount, [])

  const matchingCount = useSelector((state) =>
    selectCompletedTodosCount(state, completed)
  )

  return <div>{matchingCount}</div>
}

The version with useSelectorWith is shorter because it does the equivalent of the useMemo for you.

export const CompletedTodosCount = ({ completed }) => {
  const matchingCount = useSelectorWith(selectCompletedTodosCount, completed)

  return <div>{matchingCount}</div>
}

Neat! It's a tad spooky magic that all is done for you but it is simpler to read, might introduce this at work to replace the reselect + useMemo combo we do a bunch.

Feel free to close this issue.

@JoshuaKGoldberg
Copy link
Collaborator

@danstiner exactly, yes!

I think the root issue here is that the root README.md doesn't directly mention why you'd want such a thing. It's mentioned in https://github.com/Codecademy/use-selector-with/tree/71d0f0b/packages/use-selector-with#why but that's about it.

JoshuaKGoldberg pushed a commit that referenced this issue Oct 8, 2021
@JoshuaKGoldberg JoshuaKGoldberg added the documentation Improvements or additions to documentation label Oct 8, 2021
@JoshuaKGoldberg
Copy link
Collaborator

Added a link in #3 but if you think there's more to be done please do post again @danstiner! The explanations are all me and I would love external eyes on how to make them more reasonable sounding. 😄

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants