-
-
Notifications
You must be signed in to change notification settings - Fork 15.3k
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
How to call actions without using @connect? #362
Comments
I'm not sure is it a "right" way or not, but you can access the store through the context. See the |
The class MyComponent extends Compoenent {
static contextTypes = {
store: React.PropTypes.object.isRequired,
}
render() {
const { dispatch } = this.context.store
const actions = bindActionCreators(headerActions, dispatch)
}
} |
You should pass the dispatch down from the parent component, or the action already bound to the dispatch. That is the way I believe, context also works, albeit it's a workaround |
Thanks for explaining this! I get it now. |
You can pass |
I am a bit puzzled by this issue too. If I understand correctly, we need either to have So in the end we're just transferring our dependency of For example, what if we were in a deep hierarchy of components:
and if none of the parents needs to connect to the redux state? Having dispatch made available to a component as a side-effect of using I know that we could still access What do you think about it? Thanks! |
Why is it weird? Think of With current React Redux API it's not convenient to connect to Redux without also selecting state. You'd have to write something like Does this make sense? |
Totally makes sense now :). Can't wait to use the new API. Thanks a lot, using Redux is a bliss! |
This is available in https://github.com/gaearon/react-redux/releases/tag/v0.5.0. |
This looks great! |
@gaearon hey Dan can you give me a tip on how to use bindActionCreators with nested components: "AddProduct" - connected to redux (see below) I want ProductView to be able to dispatch, but only the master "Add Product" has:
|
You can either |
thanks Dan, really appreciate your help. really love redux too! another question if i may: thank you |
Definitely not, reducers must be pure functions free of any side effects.
Yes. Please see this guide: http://rackt.github.io/redux/docs/advanced/AsyncActions.html |
thanks Dan, works great (y) if im using server rendering for lets say getting the current user logged in, |
You can create store on the server, wait for async actions to finish, and then render. |
I'm probably missing something critical, but why not just partially-apply dispatch onto all the action-creators during app initialization? Then you could call then from anywhere without worrying about how to get a reference to dispatch. |
@mpoisot : because you'd have to know, import, bind, and distribute every potential action creator at app startup. Among other things, that doesn't help with situations like code splitting. |
@markerikson I already have to know all the reducers at app init so I can call True, you might end up pulling in slightly more code than you actually use. But if that's a concern then don't do it this way. Or break up your reducer-sets (reducer + action creators + selectors) into smaller, more focused bundles. Or only bind some action creators. Is there some terrible performance penalty for doing this? Or it somehow leads down a terrible path to coding hell? |
@mpoisot : not really any perf problems I can think of. However, it does limit testability and reusability. Proper use of |
Ah good point, partially-applying dispatch in action creators would be equivalent to importing the store as a singleton, which is frowned upon. I tried to learn why, and I found several places where Dan Abramov said a singleton store is frowned upon due to server side rendering (which most people will never use), but strange he never mentioned testing (which everyone should do, or at least feel bad about not doing). Which makes me think, surely you can create a store singleton object whose store can be updated with different stores for testing? Instead of directly exporting the store itself, return it via |
@mpoisot You just described what Provider/connect do. ;) |
Often I have a "dumb" component that one day needs dispatch (or an pre-bound action). So I wrap him in connect, or maybe pass stuff down from a containing component that's connected. It often feels like a lot of wiring and passing props just to avoid globally accessible dispatch. For mapStateToProps() there are wonderful performance gains with Provider/connect(). And for reusing dumb components it definitely makes sense extract dispatch logic to the higher order component. But I've hit this scenario enough times to wonder why. And it appears the answer is "so you can do server side rendering someday". (Please correct me if I'm wrong). |
Right now, |
Yep, some of the "component/encapsulated state" experiments I've seen work with exactly that approach. The nifty thing about that idea is that the other components don't need to know anything's changed, since the wrapper components are still just grabbing |
I've been on both sides of this -- In my primary application we treat the store as a singleton and use a globally available On the other hand, I've built an experimental app where I wrap the store (like @jimbolla and @markerikson mentioned) in various places within the component hierarchy, and both Depending on what you want to accomplish, I think the singleton store stuff is viable, but personally I'm slowly moving away from it. |
Yeah. You certainly can treat the store as an accessible singleton, but it does limit you, it's not considered idiomatic, and I don't see any real advantage to doing so. |
Thanks, great feedback. Can someone post a link showing off some store-wrapping? |
Here is one of Dan's comments that illustrates how wrapping You might have to read the whole thread to better understand what the motivation is. In particular, notice how |
Sorry for hijacking this old post as im facing the similar confusion, wishing to dispatch action without connect.
From what I understand, I can't possibly connect to store in this component as we are just configuring and pass the store into |
@isaaclem : well, in that specific case, you do have a reference to the store, so you could just directly call The other option would be to restructure your component structure so that some component inside the |
I have a header container which passes image data (url, size) down to a header component using
Then I have another component which needs to call header actions in order to update the header state. It doesn't use the state, it just fires actions. Afaik I need to do something like this:
The problem is, this.props.dispatch only seems to be available when you use the @connect decorator. The second component is not interested in the header state at all. Do I really need to use connect here or can it somehow bind the actions in a different way? It feels wrong to use @connect if I don't use the data.
The text was updated successfully, but these errors were encountered: