NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
npm · #1379 most downloaded on npm
Predictable state container for JavaScript apps
Last release 3 years ago
no release in 18 months
Release timing varies
gaps range from 2 weeks to 10 months
Nearly every release is documented
notes for 57 of the last 60 stable releases
5 versions withdrawn
withdrawn after publishing
15 years old
85 releases · first in 2011
Classes returned by decorators now expose a static DecoratedComponent property for easier testing
No breaking changes this time.
DecoratedComponent property for easier testinglodash and babel-runtime are droppedcomposeStore now ignores non-function values (useful in Babel loose mode)@@INIT type (might be useful to devtools)Bugfix: when Connector select property changes, the state did not recalculate
Connector select property changes, the state did not recalculate (#107)One column per quarter.
Renames compose root export to composeMiddleware to clarify the intent
compose root export to composeMiddleware to clarify the intentgetState returning stale state after a hot reload (#90)Missing from the 0.10 release notes: React Native is now supported! (And that's actually a breaking change.)
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:
Connector now throws if select returns something other than a plain object (https://github.com/gaearon/redux/pull/85)setState now returns the state that was actually set. This makes custom dispatchers more composable. (https://github.com/gaearon/redux/pull/77)Happy reducing!
Redux 1.0 is within striking distance! Can you believe how quickly Redux has matured? @gaearon made the first commit only 14 days ago.
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.
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().
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.
This release brings breaking changes necessary to start experimenting with middleware and extensibility (#6, #55). It does _not_ bring any support for…
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 to createReduxcreateRedux is the primary API you'll use for initializationdispatcher prop, a dispatch function prop is injected by the <Connector> and @connectdispatcher prop, <Provider> and @provide accept a redux propdispatcher.getAtom(), use redux.getState()dispatcher.setAtom(), you may pass a second initialState argument to createReduxdispatcher.perfrorm() or dispatcher.dispatch(), use redux.dispatch()bindActions is renamed to bindActionCreators and accepts dispatch as the second parametercomposeStores and createDispatcher completely and just use createRedux(stores) as a shortcutThis 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>
);
}
}
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>
);
}
}
// 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);
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)} />
);
}
}
hydrate() and dehydrate() are gone, welcome getAtom() and setAtom() instead
hydrate() and dehydrate() are gone, welcome getAtom() and setAtom() insteadinitialize() and dispose() are added for advanced use casesselect function now updates the Connector statedispatch instead of perform is fixedThis release wouldn't have happened without this @acdlite's wonderful gist.
This release wouldn't have happened without this @acdlite's wonderful gist.
New:
composeStores higher-order Store (seriously.)<Connector select={fn}> propRead the discussion: https://github.com/gaearon/redux/pull/46
Change second parameter in callback-style action creator from state to read: (Store) => state
state to read: (Store) => state (#44)Container -> Injector, @container -> @inject, Root -> Dispatcher, @root -> @dispatch (#20)@container's second parameter now also accepts the props passed to it
@container's second parameter now also accepts the props passed to it (#36)<Container /> and <Root /> invoke their this.props.children functions without this.props context- Fix incorrect ES6 Map usage
Breaking change: stores now accepts an object, just like actions
stores now accepts an object, just like actionsContainer children function signature is now ({ actions, state }) => ...Container props validationThis 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
Fix the remaining dependency on the function name
Store function names are no longer significant, but you have to pass an object with all your Stores to the root (or Root). Fixes https://github.com/ga
root (or Root). Fixes https://github.com/gaearon/redux/issues/16import { root } from 'redux';
import * as stores from './stores/index';
@root(stores)
export default class TodoApp {
import { root } from 'redux';
import * as stores from './stores/index';
export default class TodoApp {
render() {
return (
<Root stores={stores}>
Bring decorators back, now on top of the lower-level container components
stores passed to Container to be an arrayNothing published for this version
No more strings, now using module bindings for injecting stores and actions
Complete rewrite.
// The smart component may inject actions
// and observe stores using <Container />:
import React, { Component } from 'react';
import { Root, Container } from 'redux';
import { increment, decrement } from './actions/CounterActions';
import counterStore from './stores/counterStore';
import Counter from './Counter';
export default class CounterContainer {
render() {
// stores can be a single store or an array.
// actions can only be a string -> function map.
// props passed to children will combine these actions and state.
return (
<Container stores={counterStore}
actions={{ increment, decrement }}>
{props => <Counter {...props} />}
</Container>
);
}
}
Minor caveat: Store function names are now significant.
Pass state as a second argument to callback-style action creators
state as a second argument to callback-style action creatorsFix @provides not passing its props down
@provides not passing its props downSee examples in README and the examples folder.
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Nothing published for this version
Your coding agent can read these notes before it upgrades. Set up the MCP server →