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

Provider component is not intuitive for passing props #68

Closed
tiye opened this issue Aug 23, 2015 · 14 comments
Closed

Provider component is not intuitive for passing props #68

tiye opened this issue Aug 23, 2015 · 14 comments

Comments

@tiye
Copy link

tiye commented Aug 23, 2015

Previously discussed on Twitter: https://twitter.com/dan_abramov/status/635441125013200896

Related code:
https://github.com/jackielii/simplest-redux-example/blob/master/index.js#L56

React.render(
  <Provider store={store}>
    {() => <App />}
  </Provider>,
  document.getElementById('root')
);

In order to pass the props, we need one more file to bind the props:

import copy

@gaearon
Copy link
Contributor

gaearon commented Aug 23, 2015

I'm not really sure what props you have troubles passing. Root and Provider are just plumbing: they look intimidating in a tiny app, but you only need to declare them once.

What problems do you have, after Root is declared and uses Provider? Let's imagine your app starts at CounterApp.

@tiye
Copy link
Author

tiye commented Aug 23, 2015

I'm not reporting it as a bug. It may be an improvement or something.

@gaearon
Copy link
Contributor

gaearon commented Aug 23, 2015

I'm not saying I think you're reporting it as a bug :-).
I'm just trying to understand what could be improved. Can you suggest a different API?

@gaearon
Copy link
Contributor

gaearon commented Aug 23, 2015

To clarify, <Provider> is not there to pass props. It's there to make connect() work no matter how deep it is in your app hierarchy. It uses undocumented React "context" feature to do that.

@tiye
Copy link
Author

tiye commented Aug 23, 2015

I'm giving up. I just thought it can be simpler(like passing props directly), without understanding the implementation details. And probably I don't understand the true purpose behind <Provider>

And I turned my ideas into a "Redux clone for learning purpose" at https://github.com/mvc-works/actions-recorder (use gulp script or npm i actions-recorder to get JavaScript version if you need).

@tiye tiye closed this as completed Aug 23, 2015
@gaearon
Copy link
Contributor

gaearon commented Aug 23, 2015

And probably I don't understand the true purpose behind

The purpose is to expose store on the React context. As I said, context is undocumented React feature so I understand the confusion.

Without <Provider> or something similar, you can't connect() components somewhere deep in the hierarchy. connect() needs to read store somehow so it can subscribe to it. <Provider> puts store in React context so connect() can read it from there. If there was no provider, you'd have to either

a) pass the store down via props through you whole application (very verbose);
b) export a singleton store and let all components use it, but this doesn't work for apps rendering on server, because they want to have a store instance per request.

@oliviertassinari
Copy link
Contributor

And probably I don't understand the true purpose behind

Same for me. Now, I understand, thanks.

@tiye
Copy link
Author

tiye commented Aug 24, 2015

It makes sense. We even used a listenTo mixin to to the job and it's so much code.

Personaly I still prefer the verbose way since it doesn't intrduce new terms or concepts. I can see the "very verbose" way in my own solution:

React.render(Page({
  store: initial,
  records: Immutable.List(),
  pointer: -1
}), document.body);
recorder.subscribe(function (store, records, pointer) {
  return React.render(Page({
    store: store,
    records: records,
    pointer: pointer
  }), document.body);
});

@gaearon
Copy link
Contributor

gaearon commented Aug 24, 2015

Yes, and also always tendering from the top will be slower.

@tiye
Copy link
Author

tiye commented Aug 24, 2015

Did you mean React.render is slower than Component.setState()?

@gaearon
Copy link
Contributor

gaearon commented Aug 24, 2015

Yes, it's faster to setState in the middle of the view hierarchy than React.render at the top because this saves React work of figuring out that other components have not changed.

If most of your components implement shouldComponentUpdate it's not such a problem, but it's still more performant to use setState in the middle (via connect() or a custom helper—but again, connect is optimized so you should probably use it).

@tiye
Copy link
Author

tiye commented Aug 24, 2015

I prefer Immutable data in such cases :)

@gaearon
Copy link
Contributor

gaearon commented Aug 24, 2015

Immutable doesn't solve this problem. React has to reconcile the tree, whether you use Immutable or something else.

@tiye
Copy link
Author

tiye commented Aug 24, 2015

Fine.

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