-
-
Notifications
You must be signed in to change notification settings - Fork 15.2k
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
Support custom dispatchers #60
Conversation
lovely! (also, and not sure this makes sense... one can now compose dispatchers?) |
👍 |
1 similar comment
👍 |
Solves all problems. 👍 |
Hmm. Why dispatcher stores a copy of state? May be redux should pass export default function createDispatcher(store) {
return function dispatcher(getState, setState) {
setState(store(getState(), {}));
function dispatchSync(action) {
state = store(getState(), action);
setState(state);
return action;
}
function dispatch(action) {
return typeof action === 'function' ?
action(dispatch, state) :
dispatchSync(action);
}
return dispatch;
};
} |
great job. |
I wanted “only the dispatcher may set the state” to be a hard constraint. If it's not true, it's much more difficult to implement transactions, as we saw in #55. Having the dispatcher maintain the reference to state reinforces this idea—since it's the only thing that can change it, providing |
This change has a funny consequence! Now I can write const dispatcher = createUberDispatcher({ replay: true, log: true }); // can tweak options with hot reloading |
Sorry I'm just now looking at this, but yay! Looks great. |
I think you were right now about I'll change it to be |
Goals of this PR:
This PR does not try to solve middleware API or the middleware composition. Instead, it allows to implement #55 and #6 in the userland by separating “Redux instance” (the state holder) and the Dispatcher. By providing a custom Dispatcher, you can experiment with different composable middleware APIs without changing the core.
New definitions
The Dispatcher is a function responsible for turning actions into state changes. Its signature is
(initialState, setState) => (action) => ()
. You won't use it directly, and will instead hand it off to the Redux instance.The Redux instance is ignorant of how actions turn into state. It has no knowledge of dispatching, or stores. It is a facade for Redux, providing you
getState
anddispatch
, and letting you specify an initial state for hydration.The Redux library provides a default dispatcher that implements the current behavior with
createDispatcher
:The built-in Dispatcher
The default dispatcher looks like this:
As you can see,
perform
is no more. Nowdispatch
behaves exactly likeperform
used to behave because that's what the Dispatcher does.Custom Dispatchers
To provide a custom dispatcher, just don't use
createDispatcher
and pass your own function instead with the same(initialState, setState) => (action) => ()
signature.It doesn't even have to understand the concept of Stores. It may do something completely different—the only important part is that it has to translate the actions into the state updates.
Convenience API
Finally, this PR brings back a simpler convenience API for most people who don't need to customize the Dispatcher or the Store composition: