Releases: reduxjs/redux
v0.11.0
v0.10.1
Missing from the 0.10 release notes: React Native is now supported!
(And that's actually a breaking change.)
Now, to import React-specific parts (containers or decorators), you need to either import from redux/react or redux/react-native:
// Import utilities and functions from redux
import { createRedux, bindActionCreators } from 'redux';
// Import components and decorators from redux/react
import { provide, Connector } from 'redux/react';
// React Native: Import components and decorators from redux/react-native
import { provide, Connector } from 'redux/react-native';0.10 release also had a problem with ES6 code inside redux/react and redux/react-native entry points, which is now fixed. Please upgrade if you had problems with 0.10.
Changes introduced in 0.10.1:
Connectornow throws ifselectreturns something other than a plain object (#85)- The custom dispatcher API is tweaked so
setStatenow returns the state that was actually set. This makes custom dispatchers more composable. (#77)
Happy reducing!
v0.10.0
Middleware
Redux 1.0 is within striking distance! Can you believe how quickly Redux has matured? @gaearon made the first commit only 14 days ago.
The 0.10 release is a follow-up to 0.9, with a focus on what we're calling (at least for now) middleware.
You can read all about middleware here. We plan to release some official middleware soon, but of course we'd also love to see middleware created by the community.
Breaking changes
Just a small one: Redux includes a feature that enables you to return a function from an action creator to perform asynchronous dispatches. The function receives a callback and getState() as parameters. This has behavior has been re-implemented as middleware and moved into a separate module called thunkMiddleware(). It is included automatically when using the createRedux(stores) shortcut, but not when using createDispatcher().
Tests
We have tests! Still need to improve coverage in a few areas, but we're currently at ~93%. Not bad! Big thanks to @emmenko for setting these up.
v0.9.0
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.
createDispatchernow returns a function you need to give tocreateReduxcreateReduxis the primary API you'll use for initialization- Instead of
dispatcherprop, adispatchfunction prop is injected by the<Connector>and@connect - Instead of
dispatcherprop,<Provider>and@provideaccept areduxprop - Instead of
dispatcher.getAtom(), useredux.getState() - Instead of
dispatcher.setAtom(), you may pass a secondinitialStateargument tocreateRedux - Instead of
dispatcher.perfrorm()ordispatcher.dispatch(), useredux.dispatch() bindActionsis renamed tobindActionCreatorsand acceptsdispatchas the second parameter- You may skip
composeStoresandcreateDispatchercompletely 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)} />
);
}
}v0.8.1
hydrate()anddehydrate()are gone, welcomegetAtom()andsetAtom()insteadinitialize()anddispose()are added for advanced use cases- changing
selectfunction now updates theConnectorstate - the bug with action creators accepting
dispatchinstead ofperformis fixed
v0.8.0
The Big Rewrite!
This release wouldn't have happened without this @acdlite's wonderful gist.
New:
- Now there is just one top Store, but you may compose your Stores using
composeStoreshigher-order Store (seriously.) - Dispatcher is now part of the public API and offers (de)hydration for isomorphic apps.
- Fine-grained subscriptions via the new
<Connector select={fn}>prop - Less surprising, more consistent API
Read the discussion: #46
v0.7.0
v0.6.2
v0.6.1
v0.6.0
- Breaking change:
storesnow accepts an object, just likeactions - Breaking change:
Containerchildren function signature is now({ actions, state }) => ... - More fine-grained
Containerprops validation
This fixes #22. There is no more prop shape difference between subscribing to a single or to many stores.
Your container may now look like this:
<Container stores={{ counter: stores.counterStore }}
actions={{ increment, decrement }}>
{({ state, actions }) => <Counter {...state} {...actions} />}
</Container>Note that you can change the state shape by giving arbitrary keys to your stores. It's also easier to choose what exactly you want to pass to the component. For example, you could write actions={actions} instead of {...actions}, and get all actions in this.props.actions.
The decorator version is changed the same way:
@container({
actions: { increment, decrement },
stores: { counter: counterStore }
})
export default class Counter {It also now accepts a second transformProps argument to be just as expressive as the component version:
@container({
actions: { increment, decrement },
stores: { counter: counterStore }
}, ({ actions, state}) => { ...actions, ...state })) // default shape; you can write your own