Releases: reduxjs/redux-toolkit
v1.1.0
This release adds a utility function for better type safety with reducer object parameters, and fixes an issue with error message in the serializability check middleware.
Changes
Type-Safe Reducer Object Builder API
createReducer
accepts a plain object full of reducer functions as a parameter, where the keys are the action types that should be handled. While this works fine with plain JS, TypeScript is unable to infer the correct type for the action parameters in each reducer.
As an alternative, you may now pass a callback function to createReducer
that will be given a "builder" object that allows you to add reducers in a type-safe way based on the provided action types:
const increment = createAction<number, 'increment'>('increment')
const decrement = createAction<number, 'decrement'>('decrement')
createReducer(0, builder =>
builder
.addCase(increment, (state, action) => {
// action is inferred correctly here
})
.addCase(decrement, (state, action: PayloadAction<string>) => {
// this would error out
})
)
While this API is usable from plain JS, it has no real benefit there, and is primarily intended for use with TS.
The same API is also available for the extraReducers
argument of createSlice
. It is not necessary for the reducers
argument, as the action types are already being defined there.
Serialization Error Fixes
Error messages for the serialization check middleware were not correctly displaying the value. This has been fixed.
Docs Updates
Docusaurus v2
Our documentation site at https://redux-toolkit.js.org has been upgraded to use Docusaurus v2! This comes with a shiny new look and feel, and page loads are now even more Blazing Fast (TM).
Thanks to @endiliey, @yangshunz, @wgao19, and @ashakkk for all their hard work on the migration!
New "Usage with TypeScript" Page
We now have a new "Usage with TypeScript" docs page that has examples on how to correctly write and type usage of RTK.
Changelog
Code
- alternative callback-builder-style notation for actionsMap (@phryneas - #262)
- Inline values in error messages (@kevin940726 - #257)
Docs
v1.0.4: Redux Starter Kit is now Redux Toolkit!
As of v1.0.4, we've officially renamed this package from "Redux Starter Kit" to Redux Toolkit!
Please switch the installed package name from:
redux-starter-kit
to:
@reduxjs/toolkit
Read on for details.
Why A New Name?
The name "Redux Starter Kit" originated from the original discussion issue that started the project, which was titled "RFC: Redux Starter Kit". We originally published it as a personal scoped package during early development (@acemarke/redux-starter-kit
) for ease of management.
The plan was always to make it an official Redux-branded package. We had an extensive discussion of possible names. The redux-starter-kit
package name was already taken, but the owner donated it to us, and we decided to go with it.
The intent behind "Starter Kit" was that "this package is the fastest way to start a Redux project". Unfortunately, as RSK got closer to 1.0, it became apparent that the phrase "Starter Kit" was causing confusion. People told us that they assumed the package was a CLI project creation tool, a cloneable boilerplate, something that was only meant for beginners, or something you would outgrow.
Our goal is that this package should be the default standard way for users to write Redux logic. If people aren't willing to even look at it because of the word "Starter" in the name, then that needed to change.
We put up another naming discussion thread, and concluded that the best options were to A) publish it as a @reduxjs/
scoped package, and B) use the name "Toolkit".
So, the final result is a package name of "Redux Toolkit", published on NPM as @reduxjs/toolkit
, and abbrevated as RTK.
Our documentation is now published at https://redux-toolkit.js.org.
Migration
Update all dependencies and imports from redux-starter-kit
to @reduxjs/toolkit
, and update the dependency versions to 1.0.4. (There are no code changes from RSK 1.0.1 to RTK 1.0.4 - the new published versions are just README, package naming updates, and fixes for the build setup.)
The redux-starter-kit
package continues to work as-is as of v1.0.1. However, to encourage migration, we have deprecated all existing RSK versions, and will likely publish a new version of RSK that is empty and will enforce switching to @reduxjs/toolkit
.
v1.0.3
1.0.3
v1.0.1
This release includes a TS type bugfix for prepare callbacks, adds a new match
method for action creators, and re-exports additional functions from Redux.
Changes
The types for the recently added error
field in prepare callbacks were too loose, and that caused them to fall back to any
. This has been fixed.
There are cases when it is helpful to have a type guard to narrow action objects down to a known type, such as checking in a middleware. Generated action creators now have a actionCreator.match()
type guard function attached.
We were re-exporting some methods from the Redux core, but not all of them. All Redux exports are now re-exported, including bindActionCreators
.
Changelog
v1.0 Final!
Today I am extremely excited to announce that:
Redux Starter Kit 1.0 is now live!
To celebrate, I've put together a blog post that looks back at the history, inspirations, and development process that led us to this point:
Idiomatic Redux: Redux Starter Kit 1.0
Changes
This release contains only one new change: the ability to include an error
field from a prepare callback, to match the FSA standard.
Changelog
Credits and Thanks
I'd like to thank everyone who has been involved in Redux Starter Kit in any way. To highlight some of the key participants:
- @gaearon : the creator of Redux. Wouldn't have any of this without him.
- @modernserf: wrote the original suggestion that inspired RSK.
- @timdorr : wrote the RFC: Redux Starter Kit issue that served as the springboard for actually getting RSK started
- @hswolff : helped talk through the initial list of features
- @nickmccurdy : implemented almost all of the initial build tooling and several key pieces of initial functionality
- @shotaK: donated the
redux-starter-kit
package name on NPM - @neurosnap : ported
createSlice
from Autodux, and donated his implementation after writing it as a separate package - @denisw: ported RSK to TypeScript, and valuable suggestions on
createSlice
- @Dudeonyx , @Jessidhia: plenty of TS advice
- @phryneas : implemented multiple new features, improved our TS types, and coached me through starting to understand how some of this complex types stuff actually works :)
- @RichiCoder1 : ported our build setup to TSDX
Thank you so much to all of you, and everyone else who has contributed!
v0.9.1
The switch to TSDX accidentally dropped the re-export of types like Action
from Redux.
Changelog
- Fix broken re-export of Redux types d70dc31
v0.9.0
This release contains only build tooling changes and package updates. We've switched our build setup from a homegrown Rollup config to use TSDX instead. We're also running CI tests against multiple versions of TypeScript to try to prevent any future type changes that might affect older versions.
As part of the TSDX changes, the published package now contains the types in a single combined index.d.ts
file instead of separate files, which may work better in certain build tooling setups.
In the process, we've also updated Immer from 2.1.5 to 4.0.1. This primarily adds auto-freezing of all state objects in development, but shouldn't have any actual changes for your code. See the Immer release notes for more details.
Barring any new issues, this will likely be the last point release before 1.0 release candidates in the next couple days.
Changelog
- chore(build): swap in tsdx (@RichiCoder1, @phryneas, @markerikson - #212)
- Use TypeScript 3.6 in development (@nickmccurdy - #218)
- Test with multiple TypeScript minor versions in CI (@nickmccurdy - #217)
v0.8.1
v0.8.0
This release contains a couple breaking changes, including one that will affect almost all existing users. The plan is for these to be the final breaking changes before 1.0 is released, and that 1.0 will hopefully be out within the next couple weeks.
Breaking Changes
createSlice
Now Requires a name
Field
So far, createSlice
has accepted an optional field called slice
, which is used as the prefix for action types generated by that slice:
const counterSlice1 = createSlice({
slice: "counter", // or could be left out entirely
initialState: 0,
reducers: {
increment: state => state + 1,
}
});
The slice
field has been changed to name
, and is now required to be a non-empty string.
const counterSlice1 = createSlice({
name: "counter", // required!
initialState: 0,
reducers: {
increment: state => state + 1,
}
});
This removes cases where multiple slices could have accidentally generated identical action types by leaving out the slice name while having similar reducer names. The field name change from slice
to name
was made to clarify what the field means.
Migration: change all uses of slice
to name
, and add name
to any createSlice()
calls that didn't specify it already.
createAction
Defaults to a void
Payload Type
Previously, createAction("someType")
would default to allowing a payload type of any
when used with TypeScript. This has been changed to default to void
instead. This means that you must specify the type of the payload, such as createAction<string>("someType")
.
Note that this is not necessary when using createSlice
, as it already infers the correct payload types based on your reducer functions.
Migration: ensure that any calls to createAction()
explicitly specify the payload type as a generic.
Other Changes
createSlice
Exports the Case Reducer Functions
createSlice
already returned an object containing the generated slice reducer function and the generated action creators. It now also includes all of the provided case reducers in a field called caseReducers
.
const todosSlice = createSlice({
name: "todos",
initialState: [],
reducers: {
addTodo(state, action) {
const {id, text} = action.payload;
state.push({id, text});
},
toggleTodo(state, action) {
const todo = state[action.payload.index];
todo.completed = !todo.completed
}
},
extraReducers: {
["app/logout"](state, action) {
return []
}
}
});
console.log(todosSlice)
/*
{
name: "todos",
reducer: Function,
actions: {
addTodo: Function,
toggleTodo: Function,
},
caseReducers: {
addTodo: Function,
toggleTodo: Function
}
}
*/
Notes
Special thanks to @phryneas for coaching me through finally starting to get a vague grasp on some very complicated TS types :)
Changelog
- Create slice changes (@phryneas - #197)
- Include case reducers in createSlice result (@markerikson - #209)
- Use
void
instead ofany
for undefined payloads (@Krisztiaan , @markerikson - #174) - Improve reducer warning (@markerikson - #207)
- change inference behaviour in old TS versions (@phryneas - #166)
v0.7.0
This release introduces some noticeable breaking changes as we begin working our way towards 1.0.
Breaking Changes
Removal of Selectorator
RSK previously exported the createSelector
function from https://github.com/planttheidea/selectorator . Selectorator wraps around Reselect, and the main selling point was that its createSelector
wrapper accepted string keypath "input selectors".
However, this capability made usage with TypeScript almost useless, as the string keypaths couldn't be translated into the actual types for the values that were being extracted. Ultimately, there wasn't enough real benefit for keeping this around, and so we are removing Selectorator.
We now simply export createSelector
directly from https://github.com/reduxjs/reselect instead.
Migration
Replace any string keypath usages with actual selector functions:
// before
const selectAB = createSelector(
["a", "b"],
(a, b) => a + b
);
// after
const selectA = state => state.a;
const selectB = state => state.b;
const selectAB = createSelector(
[selectA, selectB],
(a, b) => a + b
);
Removal of "slice selectors"
createSlice
tried to generate a "slice selector" function based on the provided slice name. This was basically useless, because there was no guarantee that the reducer function was being combined under that name. The dynamic name of the generated function also made it hard to use.
Migration
Remove any uses of slice.selectors
(such as slice.selectors.getTodos
). If necessary, replace them with separate hand-written calls to createSelector
instead.
Other Changes
Customization of Default Middleware
The default middleware array generated by getDefaultMiddleware()
has so far been a black box. If you needed to customize one of the middleware, or leave one out, you were forced to hand-initialize the middleware yourself.
getDefaultMiddleware
now accepts an options object that allows selectively disabling specific middleware, as well as passing options to each of the middleware (such as redux-thunk
's extraArgument
option).
New Tutorials!
We've added a set of new tutorial pages that walk you through how to use RSK:
- Basic Tutorial: introduces the RSK APIs in a vanilla JS page
- Intermediate Tutorial: shows how to use RSK in a CRA app, by converting the standard Redux "todos" example to use RSK
- Advanced Tutorial: shows how to use RSK with TypeScript, thunks for async and data fetching, and React-Redux hooks, by converting a plain React app to use RSK
Changelog
- Remove slice selectors (@markerikson - #193)
- Enable customizing default middleware and store enhancers (@markerikson - #192)
- Remove Selectorator (@markerikson - #191)
- Refactor typings for readability (@phryneas - #168)