Skip to content

Commit

Permalink
Enable initial migrations, clarify README (#14)
Browse files Browse the repository at this point in the history
* Allow currentVersion of `0`

Previously a `0` would be interpreted as falsy, but I believe
the real intent here is to avoid an undefined due to an empty
`versionKeys` array.

* Allow migrations upon first use of redux-persist-migrate

Previously, if there was not already a stored version, migrations would
not happen at all.  This change allows _all_ migrations to occur, the
first time redux-persist-migrate is deployed and users have stored
state, but no stored version.

I think this is safe, because the only other realistic time the version
will be null is when persisted data has been purged, in which case there
will be no other `state` to migrate.  

The only other situation I can think of which might cause problems, is 
if the developer has not created a reducer at all in which to store the
version.  In that case, all migrations will be performed, but the new
version will not be saved, so the migrations will occur each time.  I
think the solution to this is to improve the documentation to clarify
that a reducer needs to be created to store the version, and that
`redux-persist-migrate` will not create any reducers.

* Clarify that an existing reducer is needed

Fixes #9
  • Loading branch information
IanVS authored and rt2zz committed Aug 30, 2017
1 parent e2939f2 commit 033d818
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 14 deletions.
28 changes: 20 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,26 +4,38 @@ Migrate redux state between versions with redux-persist.

#### Usage
```js
import { compose, createStore } from 'redux'
import { compose, createStore, combineReducers } from 'redux'
import { persistStore, autoRehydrate } from 'redux-persist'
import createMigration from 'redux-persist-migrate'

// VERSION_REDUCER_KEY is the key of the reducer you want to store the state version in.
// You _must_ create this reducer, redux-persist-migrate will not create it for you.
// In this example after migrations run, `state.app.version` will equal `2`
const VERSION_REDUCER_KEY = 'app'

// This is a list of changes to make to the state being rehydrated.
// The keys must be integers, and migrations will be performed in ascending key order.
// Note: blacklisted reducers will not be present in this state.
const manifest = {
1: (state) => ({...state, staleReducer: undefined})
2: (state) => ({...state, app: {...state.app, staleKey: undefined}})
1: (state) => ({...state, staleReducer: undefined})
2: (state) => ({...state, app: {...state.app, staleKey: undefined}})
}

// reducerKey is the key of the reducer you want to store the state version in
// in this example after migrations run `state.app.version` will equal `2`
let reducerKey = 'app'
const migration = createMigration(manifest, reducerKey)
const migration = createMigration(manifest, VERSION_REDUCER_KEY)
const enhancer = compose(migration, autoRehydrate())

const reducer = combineReducers({
[VERSION_REDUCER_KEY]: (state = {}) => state, // This reducer will be used to store the version
otherReducer1,
otherReducer2,
// ...
})

const store = createStore(reducer, null, enhancer)
persistStore(store)
```

In the above example `migration = createMigration(manifest, 'app')` is equivalent to the more generalized syntax:
In the above example `migration = createMigration(manifest, VERSION_REDUCER_KEY)` is equivalent to the more generalized syntax:
```js
// alternatively with version selector & setter
const migration = createMigration(
Expand Down
11 changes: 5 additions & 6 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export default function createMigration (manifest, versionSelector, versionSette

const versionKeys = Object.keys(manifest).map(processKey).sort((a, b) => a - b)
let currentVersion = versionKeys[versionKeys.length - 1]
if (!currentVersion) currentVersion = -1
if (!currentVersion && currentVersion !== 0) currentVersion = -1

const migrationDispatch = (next) => (action) => {
if (action.type === REHYDRATE) {
Expand All @@ -40,11 +40,10 @@ export default function createMigration (manifest, versionSelector, versionSette
}

const migrate = (state, version) => {
if (version != null) {
versionKeys
.filter((v) => v > version)
.forEach((v) => { state = manifest[v](state) })
}
versionKeys
.filter((v) => v > version || version === null)
.forEach((v) => { state = manifest[v](state) })

state = versionSetter(state, currentVersion)
return state
}
Expand Down

0 comments on commit 033d818

Please sign in to comment.