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

I want to use "Dumb Components" #134

Closed
kswope opened this issue Jun 18, 2015 · 9 comments
Closed

I want to use "Dumb Components" #134

kswope opened this issue Jun 18, 2015 · 9 comments
Labels

Comments

@kswope
Copy link

kswope commented Jun 18, 2015

But I guess I'm too dumb to understand how. Do the docs actually show anywhere how stores/actions/dispatcher interact when not using all the magicality of smart components and shortcuts like bindActionCreators. If they don't consider this a request for more documentation.

@dariocravero
Copy link
Contributor

@kswope in the Counter example this is a dumb component and this one smart. Isn't it here?

@emmenko
Copy link
Contributor

emmenko commented Jun 18, 2015

Consider a Dumb Component a component that purely renders. That means i receives what it needs via props (and shouldn't have any state).

A Smart Component is what is often called a Container component. The responsibilities here are handling data changes, meaning it subscribes to store changes, it can have a state and trigger actions.

To recap:

  • dumb: pure render using props
  • smart: handles data changes and renders dumb component by passing data via props

@gaearon
Copy link
Contributor

gaearon commented Jun 18, 2015

If you put <Provider> at the root, you're going to end up with redux in your context (if you want to do all the wiring yourself you'll need to know about React's context).

Then you can use redux.dispatch to dispatch actions and redux.subscribe(listener) to subscribe to the root state update. It's up to you to select from it the state your component is actually interested it.

Because most components are only interested in a particular slice of the global state (akin to subscribing to a Store), Redux providers <Connector> component that does that for you. <Connector> lets you specify a custom state selector function (<Connector select={state => ({ users: state.users })}>), and it will inject the object you returned and the dispatch function into its children:

function select(state) {
  return { counter: state.counter };
}

export default class CounterApp {
  render() {
    return (
      <Connector select={select}>
        {({ counter, dispatch }) =>
          <Counter counter={counter}
                   dispatch={dispatch} />
        }
      </Connector>
    );
  }
}

Now Counter can dispatch actions by calling this.props.dispatch(CounterActions.increment()), but for convenience, there is a bindActionCreators method that wraps each passed action creator in a dispatch call.

Does this make sense?

@gaearon
Copy link
Contributor

gaearon commented Jun 18, 2015

how stores/actions/dispatcher interact

Action creators are just pure functions so they don't interact with anything. Components need to call dispatch(action) (or use bindActionCreators that wraps it) to dispatch an action returned by the action creator.

Stores are just pure functions too so they don't need to be “registered” in the traditional sense, and you can't subscribe to them directly. They're just descriptions of how data transforms. So in that sense they don't “interact” with anything either, they just exist, and are used by the dispatcher for computation of the next state.

Now, the dispatcher is more interesting. You pass all the Stores to it, and it composes them into a single Store function that it uses for computation. The dispatcher is also a pure function, and it is passed as configuration to createRedux, the only stateful thing in Redux. By default, the default dispatcher is used, so if you call createRedux(stores), it is created implicitly.

To sum it up: there is a Redux instance at the root of your app. It binds everything together. It accepts a dispatcher (which itself accepts Stores), it holds the state, and it knows how to turn actions into state updates. Everything else (components, for example) subscribes to the Redux instance. If something wants to dispatch an action, they need to do it on the Redux instance.

There is no other “interaction” in Redux.

@hungtuchen
Copy link

the previous comment worth a whole section on readme.md or something,
totally clear my mind after working on source code for a while.
very light but helpful explanation
@gaearon 👍

gaearon added a commit that referenced this issue Jun 18, 2015
@damassi
Copy link

damassi commented Jun 18, 2015

It would be great if there was more documentation around using Redux without Connectors and Providers -- how to subscribe, unsubscribe and so on, essentially removing some of the magic in favor of explicitness and a fully documented API.

@gaearon
Copy link
Contributor

gaearon commented Jun 18, 2015

It would be great if there was more documentation around using Redux without Connectors and Providers -- how to subscribe, unsubscribe and so on, essentially removing some of the magic in favor of explicitness and a fully documented API.

Agreed. @acdlite is leading the new docs effort in #137, I'm sure he'll consider it!

@damassi
Copy link

damassi commented Jun 18, 2015

Awesome, thanks @acdlite :) The docs for Flummox are great and I'm really rooting for a similar effort to be put into Redux, particularly in exposing some of the internals / patterns around wrappers and data flow.

@acdlite acdlite mentioned this issue Jun 18, 2015
13 tasks
vramana pushed a commit to vramana/redux that referenced this issue Jun 18, 2015
@bstro
Copy link

bstro commented Jun 22, 2015

+1 to more documentation using Redux without Connectors/Providers, a bit stuck at the moment

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

7 participants