enpit / fleux

Towards Sane State Management in React

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

`mapStateToProps`

objectliteral opened this issue · comments

Currently, component's can only access individual store keys. If a component wants to render aggregate data (or some selection of raw store data), it has to internally compute the aggregation. Not only is this not directly reusable (although that can easily fixed by encapsulating the aggregation into a function that is brought into scope in all components that need it), but it can also cause unnecessary rerenders: E.g. if the store contains an array of objects and a component only wants to display the number of objects in that array - such a case, the component should only get rerendered if the length of the array changes, but not, if any object properties of the objects inside the array change.

Suggestion: Implement functionality that is equivalent to Redux' mapStateToProps: A function mapping the whole store to the prop names and values that will be injected into a component.

This should remain completely optional to use and a simple string array of store key names should still be acceptable.

An implementation of this feature is available on branch feature/mapStateToProps.

The mapping of store keys to component props is now more powerful than it was before: While withState can still be invoked with a list of store key names as strings, the new invocation style supports multiple different semantics: If the first argument to withState is...

  • an array, it is interpreted as an array of store key names, creating the same store key mapping that a list of strings achieves,
  • an object, it is interpreted as a map of component local prop names to store key names,
  • a function, it is interpreted as a selectStateProps function which is fleux's equivalent of Redux's mapStateToProps function. selectStateProps receives the store and the component's own props and is expected to return an object where the keys will be used as the component local prop names and the values are - well - the values of these props.

This change involved some internal refactoring such that now we no longer use currentlyRenderingComponent.setState as the hard-coded callback for key changes, but a callback that calls selectStateProps. Not only does that better decouple the store from React-specific calls, but even more importantly achieves two things:

  • Because of the smart subscriptions implemented via the secret store getter, selectStateProps gets only called for changes to keys that it actually reads.
  • The return value of selectStateProps is compared to its previous value and the component is only rerendered if the props actually changed.

The features that were planned in the context of this issue have been implemented, tests have been written. The documentation still needs to be updated.