v0.9.0
Pre-release
Pre-release
Internal Refactoring & Custom Dispatchers
This release brings breaking changes necessary to start experimenting with middleware and extensibility (#6, #55). It does not bring any support for middleware per se, but it untangles “Dispatcher” (a function that tells how actions turn into state updates) from “Redux” (an instance holding the current state and managing subscriptions). It is now possible to specify your own Dispatcher if you want to experiment with ideas like middleware, time travel, action creators returning Promises or Observables, etc.
createDispatcher
now returns a function you need to give tocreateRedux
createRedux
is the primary API you'll use for initialization- Instead of
dispatcher
prop, adispatch
function prop is injected by the<Connector>
and@connect
- Instead of
dispatcher
prop,<Provider>
and@provide
accept aredux
prop - Instead of
dispatcher.getAtom()
, useredux.getState()
- Instead of
dispatcher.setAtom()
, you may pass a secondinitialState
argument tocreateRedux
- Instead of
dispatcher.perfrorm()
ordispatcher.dispatch()
, useredux.dispatch()
bindActions
is renamed tobindActionCreators
and acceptsdispatch
as the second parameter- You may skip
composeStores
andcreateDispatcher
completely and just usecreateRedux(stores)
as a shortcut
How It Looks Like Now
Initialization
Short Way
This is a shortcut for the most common use case.
import { createRedux, Provider } from 'redux';
import * as stores from '../stores/index';
const redux = createRedux(stores);
export default class App {
render() {
return (
<Provider redux={redux}>
{() =>
<CounterApp />
}
</Provider>
);
}
}
Long Way
This way of writing lets you use compose Stores differently, or even pass a custom Dispatcher function. Its signature is (initialState, setState) => (action) => ()
.
import { createRedux, createDispatcher, composeStores } from 'redux';
import * as stores from '../stores/index';
// Compose all your Stores into a single Store function with `composeStores`:
const store = composeStores(stores);
// Create a default Dispatcher function for your composite Store:
const dispatcher = createDispatcher(store); // You may use your custom function here
// Create a Redux instance using the dispatcher function:
const redux = createRedux(dispatcher);
export default class App {
render() {
return (
<Provider redux={redux}>
{() =>
<CounterApp />
}
</Provider>
);
}
}
Hydration and dehydration
// server
const redux = createRedux(stores);
redux.dispatch(MyActionCreators.doSomething()); // fire action creators to fill the state
const state = redux.getState(); // somehow pass this state to the client
// client
const initialState = window.STATE_FROM_SERVER;
const redux = createRedux(stores, initialState);
Binding actions
import React from 'react';
import { connect, bindActionCreators } from 'redux';
import Counter from '../components/Counter';
import * as CounterActions from '../actions/CounterActions';
@connect(state => ({
counter: state.counter
}))
export default class CounterApp {
render() {
const { counter, dispatch } = this.props;
return (
<Counter counter={counter}
{...bindActionCreators(CounterActions, dispatch)} />
);
}
}