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

Rule proposal: no impure mapStateToProps #20

Closed
lencioni opened this issue Mar 9, 2018 · 9 comments
Closed

Rule proposal: no impure mapStateToProps #20

lencioni opened this issue Mar 9, 2018 · 9 comments

Comments

@lencioni
Copy link

lencioni commented Mar 9, 2018

Since connected components are PureComponents, it is important for mapStateToProps to avoid creating new objects with identical data every time. If this happens, it will cause unnecessary re-renders, leading to bad performance.

Writing a rule to catch all of these scenarios might be too difficult, but there is probably a subset of scenarios that could be trivially linted against. Consider the following mapStateToProps:

function mapStateToProps(state) {
  return {
    foo: {
      bar: state.foobar,
    },
  };
}

What do you think about adding a rule that flags a few of these simple cases?

@DianaSuvorova
Copy link
Owner

@lencioni, can you elaborate? What the correct mapStateToProps would look like for this use case? Do we want to enforce that the props is a flat object?

@lencioni
Copy link
Author

lencioni commented Mar 9, 2018

A flat object would be okay if the components work that way. But, this is also a problem for arrays, e.g. this will always cause re-renders:

function mapStateTopProps(state) {
  return {
    foo: [],
  };
}

In this case, if it is always an empty array, you could hoist the definition of the empty array to the module level, so it is always referentially equivalent.

Another option is to use something like reselect.

I think the purpose of this rule would not be to enforce a flat object, but just to point out the unnecessary creation of new objects that cause re-renders. The documentation can point to some possible solutions, based on the specific situation.

@DianaSuvorova
Copy link
Owner

i see, this makes sense, let me generate the list of test cases first and run it by you.
Also the no-impure doesn't really sound to me descriptive of what this rule is trying to do. I don't have better suggestions though at the moment.

@lencioni
Copy link
Author

lencioni commented Mar 9, 2018

Yeah, agreed on the naming. Maybe there's some terminology from react-redux we can use?

@DianaSuvorova
Copy link
Owner

I think It might make sense to create 2 new rules as per your suggestion instead:
One is mapStateToProps-prefer-hoisted
I have created a PR for that. This one flags all the "constant" objects created inside of mapStateToProps.

The other one is mapStateToProps-prefer-flat-props but this one depends on component implementation, so at most we could add a warning on mapStateToProps level.

@lencioni
Copy link
Author

Ah interesting! I think the prefer-hoisted probably makes sense. I'm not entirely convinced about prefer-flat though, since that issue can often be solved via memoization, like with reselect. Same logic to detect, so probably just need to sort out the naming/documentation to make this clear. Not entirely sure what might be a good name though.

@DianaSuvorova
Copy link
Owner

Yeah, I am not sure about prefer-flat either. It is not always the best way to store props. Sometimes underlying structure makes a lot of sense. And yes, reselect seems like a better solution anyways.

let me see if @ljharb can take a look at my prefer-hoisted PR.

@ljharb
Copy link
Collaborator

ljharb commented Mar 20, 2018

Sorry for the delay :-) It's on my list to look at post-traveling. (altho it looks like you've already merged it, which is fine!)

@DianaSuvorova
Copy link
Owner

@ljharb , welcome back! Let me know if you have comments on the PR.

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

No branches or pull requests

3 participants