question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Investigate passing specific properties to React components

See original GitHub issue

Instead of passing the entire store.

Note: This will be hard to type safely.

Pros:

  • Let React do the diffing instead of doing it ourselves
  • Avoids the need to watch specific properties for changes and calling forceRender
  • Users can prevent renders with shouldComponentUpdate, and use other lifecycle methods

Alternative: Use an immutable data structure to back store, so the reference changes.

Cons:

  • Asymmetrical API for getting/setting (fixed by #7):

    withStore()(({ foo, bar, set }) =>
     <div onClick={() => set('bar')(3)}>
       {foo}
       {bar}
     </div>
    
  • Precludes an API where we automatically infer what to watch based on what is used. We can’t infer types from the arguments (unless there’s a clever trick I haven’t thought of), and passing store directly lets us do this

Issue Analytics

  • State:open
  • Created 6 years ago
  • Comments:6 (2 by maintainers)

github_iconTop GitHub Comments

1reaction
emmanuelbuahcommented, Mar 13, 2018

Jumping in here. @danawoodman is spot on in terms of decoupling component implementation from the store per react style. @bcherny you are also right for I was drawn to undux because of its simplicity. I think the biggest gain undux provides is getting rid of all the action/reducer boilerplate that comes with redux. Anyone using undux will be using react and will have to understand the concept of HOC sooner rather than later. From my point of view, going with option 1 or 2 is still far better than redux with boilerplate. In short, I don’t think going in any of the proposed options takes way the simplicity of the library compared to the status quo.

With that said, it also possible to offer the current api (passing the store into the component) as more or less a beginners level and the decoupled options per @danawoodman suggest for advanced usage. That should mitigate the risk of getting people up and running while providing a path for advanced usage as your application grows.

Personally, I think that will add complexity and might be best to roll with something along the lines of options 1 or 2 but you know best.

I’d also like to propose the 3rd option below which is a slight modification on option 1. This helps address the issue of what props come from where. ownProps depicts properties pass by react to the component.

export default withStore(
   // subscribe to changes to store value 'messages' similar to redux#mapStateToProps
   'messages',
   // similar to redux#mapDispatchToProps to update store state
   ({ set, ownProps }) => ({
     markAsRead() {
       set('messages', [])
     },
     ...ownProps
   }),
   Welcome
  )
0reactions
bchernycommented, Mar 4, 2018

Personally, this is the main turn-off for me with undux because IMHO it goes against React conventions. It feels wrong to call getter methods in my components. This also breaks the separation of concerns since now my component is bound to a method .get('foo') instead of just expecting a normal prop foo. Say I decide to stop using undux one day, now I have to go through all my components and replace the .get(...) calls.

@danawoodman Thanks for the feedback! Your proposed API looks reasonable, and your concerns are really fair. The one reason I haven’t jumped on this issue is that I love how simple and easy to understand a single store prop is. Even if I’ve never worked with Redux (or even React) before, I’ve probably seen stores before, and the getter/setter API is really familiar. When I see store, I know what it is intuitively. With asymmetrical getters and setters, it’s not so clear - I have to know about closures, spreads, and be familiar with how Undux works to use it (ie. I have to know that Undux spreads its store over a component’s props).

Your Option 1 is nice, and is reminiscent of how Redux does it; I love how it helps decouple components from the underlying store, so as you said, you can swap out the store implementation without updating component code. The downside of this decoupling, I think, is indirection. It’s no longer clear where props come from: this could be a good thing, or a bad thing; it’s a good thing because it makes my component independent from the store API, and it’s a bad thing because now it’s hard to see where props come from at a glance at the component (as I mentioned, how have to understand a whole bunch of concepts to grok how props are getting there).

What do you think?

Read more comments on GitHub >

github_iconTop Results From Across the Web

React.Component
React lets you define components as classes or functions. ... When called, it should examine this.props and this.state and return one of the...
Read more >
Working with Data in React: Properties & State - SitePoint
Data within React Components is stored as either properties or state. Properties are the input values to the component.
Read more >
RegExp to find React Components with specific properties on ...
Sometimes the component has so many props that the company code style would want it to split it on several lines, 1 property...
Read more >
Passing State of Parent to Child Component as Props
Setting up State in the Parent Component ... Now, examine what you have so far step by step. ... React (as expected) and...
Read more >
The mystery of React Element, children, parents and re-renders
Now, we know that React components re-render themselves and all their children when the state is updated. In this case, on every mouse...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found