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

Implement reselect recommendations and best practices #2823

Merged

Conversation

joeyparis
Copy link

This implements the reselect recommendations in this comment. It is one of the To Dos on #2812.

I believe I have fully refactored the usage of reselect in the containers, templates, generators, and tests per @markerikson's recommendations. Test coverage and success remains at 100%, although I will be honest I am relatively new at test suites, and someone should probably double-check my work.

React Boilerplate

Thank you for contributing! Please take a moment to review our contributing guidelines
to make the process easy and effective for everyone involved.

Please open an issue before embarking on any significant pull request, especially those that
add a new library or change existing tests, otherwise you risk spending a lot of time working
on something that might not end up being merged into the project.

Before opening a pull request, please ensure:

  • [✔️] You have followed our contributing guidelines
  • [❌] Double-check your branch is based on dev and targets dev
    -- Not relevant for the nature of this pull request
  • [✔️] Pull request has tests (we are going for 100% coverage!)
  • [✔️] Code is well-commented, linted and follows project conventions
  • [✔️] Documentation is updated (if necessary)
  • [✔️] Internal code generators and templates are updated (if necessary)
  • [✔️] Description explains the issue/use-case resolved and auto-closes related issues

Be kind to code reviewers, please try to keep pull requests as small and focused as possible :)

IMPORTANT: By submitting a patch, you agree to allow the project
owners to license your work under the terms of the MIT License.

markerikson and others added 30 commits November 21, 2019 10:46
  - Merged App and HomePage slices
  - RepoListItem becomes a component since we determine ownership of repo in the saga
  - Delete all useless actions/constants/reducer files
  - Update all broken tests
- Add ESLint exception for reducer files
- Add tests to improve coverage
* Update generators for switch to Redux Toolkit

* Remove useless comments from tests

* Turn multiline comment into many single line comments ;)
# Conflicts:
#	app/containers/App/index.js
#	app/containers/LanguageProvider/reducer.js
#	app/containers/LocaleToggle/index.js
#	internals/templates/containers/LanguageProvider/reducer.js
#	package.json
@coveralls
Copy link

coveralls commented Nov 25, 2019

Coverage Status

Coverage remained the same at 100.0% when pulling 6bd8e69 on joeyparis:redux-toolkit-switch into 764a9b8 on react-boilerplate:v5-with-cra.

@julienben
Copy link
Member

Thanks a lot for implementing this @joeyparis! At first glance, it looks like exactly what was needed. Will review in full tomorrow. Also, we might want to merge this into dev directly after #2812 as the squash merge will overwrite your contribution history.

selectRouter,
routerState => routerState.location,
);
const selectLocation = createSelector(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hi @joeyparis - is there a reason you removed the closures?

we wrap selectors in factories so that each selector instance maintains a private cache for memoization when using across different components, see:

https://github.com/reduxjs/reselect#sharing-selectors-with-props-across-multiple-component-instances

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @justingreenberg, I was really strictly following this comment, which was one of the To Do's. So honestly I can't say I put any deep thought into the use of factories or lack thereof. If you feel there's an alternative way to use factories, and align with the to-do/comment I'm all ears!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right, and per my comments, the existing code is doing that unnecessarily. There's no reason to have multiple selector instances all reading the exact same single value. The factory pattern is only needed when you will be calling the "same" selector with varying inputs, such as const todo = selectTodoById(state, ownProps.id). In that case, the inconsistent parameters would cause a single selector instance to not memoize at all, so you need separate instances (usually per component).

I talked about this in more detail here:

https://blog.isquaredsoftware.com/2017/12/idiomatic-redux-using-reselect-selectors/

Copy link
Author

@joeyparis joeyparis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for implementing this @joeyparis! At first glance, it looks like exactly what was needed. Will review in full tomorrow. Also, we might want to merge this into dev directly after #2812 as the squash merge will overwrite your contribution history.

Awesome, sounds like a plan! Just let me know if I need to change which branch it's being merged into.

Comment on lines 34 to 39
const stateSelector = createStructuredSelector({
username: makeSelectUsername(),
repos: makeSelectRepos(),
loading: makeSelectLoading(),
error: makeSelectError(),
});
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I opted for removing createStructuredSelector because of the consideration for removing reselect as a dependency. It does lead to using 4 separate useSelector hooks rather than one deconstructed one. I'm not sure if this is desirable or not, so I'm definitely up for discussing other alternatives!

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that's correct. You could also remove reselect from package.json as well.

selectRouter,
routerState => routerState.location,
);
const selectLocation = createSelector(
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @justingreenberg, I was really strictly following this comment, which was one of the To Do's. So honestly I can't say I put any deep thought into the use of factories or lack thereof. If you feel there's an alternative way to use factories, and align with the to-do/comment I'm all ears!

@julienben
Copy link
Member

To me this looks good.

@justingreenberg Do you still have objections or are you satisfied by the explanation given by @markerikson? Will wait for your reply to do anything about this branch.

And in any case, this will go directly into dev only after the Redux Toolkit switch is done. (I'm making progress on the documentation updates.)

Copy link
Member

@gretzky gretzky left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This LGTM as well

@justingreenberg
Copy link
Member

@joeyparis thanks for clarifying 👍🏼 @julienben yes LGTM! 😊

@joeyparis
Copy link
Author

Do I need to do anything at this time? Or are we just waiting until the Redux Toolkit switch is done? Thanks for the feedback everyone!

@julienben
Copy link
Member

julienben commented Nov 27, 2019 via email

# Conflicts:
#	app/containers/App/selectors.js
#	package.json
# Conflicts:
#	.all-contributorsrc
#	app/containers/App/selectors.js
#	app/containers/HomePage/selectors.js
#	app/containers/LanguageProvider/index.js
#	app/containers/LanguageProvider/selectors.js
#	app/containers/LocaleToggle/index.js
#	internals/templates/containers/App/selectors.js
#	internals/templates/containers/LanguageProvider/index.js
#	internals/templates/containers/LanguageProvider/selectors.js
@Can-Sahin
Copy link
Member

In app/containers/ReposManager/selectors.js did you forget to import createSelector from @reduxjs/toolkit ? Because reselect isn't need anymore

// import { createSelector } from 'reselect'; // INSTEAD
import { createSelector } from '@reduxjs/toolkit'; 

@joeyparis
Copy link
Author

@Can-Sahin looks like I did. Fixed and updated!

Copy link

@pedro-victor pedro-victor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apart from the .all-contributorsrc and removing reselect from package.json, I think this PR does basically what I have been using on my own projects (which I mistakenly pushed #2921 ) and looks to be in line with the recommendations.

"contributions": [
"code"
]
},

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this modification breaks the file.

Comment on lines 34 to 39
const stateSelector = createStructuredSelector({
username: makeSelectUsername(),
repos: makeSelectRepos(),
loading: makeSelectLoading(),
error: makeSelectError(),
});

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that's correct. You could also remove reselect from package.json as well.

@Can-Sahin Can-Sahin changed the base branch from redux-toolkit-switch to v5-with-cra July 3, 2020 13:14
@Can-Sahin
Copy link
Member

Merging due to the major v5 release. Read the discussion here

@Can-Sahin Can-Sahin merged commit fe5198f into react-boilerplate:v5-with-cra Jul 3, 2020
@Can-Sahin
Copy link
Member

Edit: Sorry for merging this somewhere else due to #2935. If you want please re submit this PR to the dev branch if that means anything to you

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

Successfully merging this pull request may close these issues.

None yet

9 participants