├── .babelrc ├── .gitignore ├── .npmignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── circle.yml ├── package.json ├── src └── index.js └── test └── index.test.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["es2015"] 3 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | !.gitignore 2 | !.npmignore 3 | !.babelrc 4 | 5 | *.log 6 | node_modules/ 7 | *.DS_Store 8 | 9 | lib/ 10 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | !.gitignore 2 | !.npmignore 3 | .babelrc 4 | circle.yml 5 | 6 | *.log 7 | node_modules/ 8 | *.DS_Store 9 | 10 | test/ 11 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## Change Log 2 | 3 | ### 0.3.0 (2017/02/18 13:08 +00:00) 4 | - [#4](https://github.com/wwayne/redux-reset/pull/4) add enhancer (@gorangajic) 5 | 6 | ### 0.2.0 (2016/05/05 10:40 +00:00) 7 | - [#2](https://github.com/wwayne/redux-reset/pull/2) Specific new state after reset (@wwayne) -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 Wang Zixiao 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # redux-reset 2 | [![Version](http://img.shields.io/npm/v/redux-reset.svg)](https://www.npmjs.org/package/redux-reset) 3 | [![js-standard-style](https://img.shields.io/badge/code%20style-standard-brightgreen.svg?style=flat)](https://github.com/feross/standard) 4 | [![Circle CI](https://circleci.com/gh/wwayne/redux-reset/tree/master.svg?style=svg)](https://circleci.com/gh/wwayne/redux-reset/tree/master) 5 | 6 | ## Installation 7 | 8 | ```sh 9 | npm install redux-reset 10 | ``` 11 | 12 | ## Basic Usage 13 | 1.Setup in createStore 14 | 15 | ```JavaScript 16 | import reduxReset from 'redux-reset' 17 | ... 18 | const enHanceCreateStore = compose( 19 | applyMiddleware(...), 20 | reduxReset() // Will use 'RESET' as default action.type to trigger reset 21 | )(createStore) 22 | const store = enHanceCreateStore(reducers) 23 | ``` 24 | 25 | 26 | 2.Dispatch reset action 27 | 28 | ```JavaScript 29 | store.dispatch({ 30 | type: 'RESET' 31 | }) 32 | ``` 33 | 34 | ## Advanced Usage 35 | #### Set any custom action.type to trigger reset 36 | 37 | ```JavaScript 38 | import Enum from 'es6-enum' 39 | const APP = Enum('RESET') 40 | 41 | const enHanceCreateStore = compose( 42 | applyMiddleware(...), 43 | reduxReset(APP.RESET) // Set action.type here 44 | )(createStore) 45 | const store = enHanceCreateStore(reducers) 46 | 47 | AFTER: 48 | store.dispatch({ 49 | type: APP.RESET 50 | }) 51 | ``` 52 | 53 | #### Reset and specific to a new initial state 54 | 55 | ```JavaScript 56 | store.dispatch({ 57 | type: 'RESET', 58 | state: {app: {user: 'anotherUser'}} // Will use this as new initial state 59 | }) 60 | ``` 61 | 62 | #### Reset and specific to a new initial state, new state comes from a specific params in action 63 | 64 | ```JavaScript 65 | import Enum from 'es6-enum' 66 | const APP = Enum('RESET') 67 | 68 | const enHanceCreateStore = compose( 69 | applyMiddleware(...), 70 | reduxReset({ 71 | type: APP.RESET, 72 | data: 'initialStateComesFrom' 73 | }) 74 | )(createStore) 75 | const store = enHanceCreateStore(reducers) 76 | 77 | AFTER: 78 | store.dispatch({ 79 | type: APP.RESET, 80 | initialStateComesFrom: {app: {user: 'anotherUser'}} 81 | }) 82 | ``` 83 | 84 | ## License 85 | 86 | MIT 87 | -------------------------------------------------------------------------------- /circle.yml: -------------------------------------------------------------------------------- 1 | machine: 2 | node: 3 | version: 5.9.0 4 | 5 | dependencies: 6 | override: 7 | - npm install -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "redux-reset", 3 | "version": "0.3.0", 4 | "description": "reset redux state", 5 | "main": "lib/index.js", 6 | "scripts": { 7 | "lint": "./node_modules/.bin/standard --verbose | snazzy", 8 | "test": "npm run lint && ./node_modules/.bin/tape -r babel-register ./test/index.test.js | tap-spec", 9 | "build": "./node_modules/.bin/babel src -d lib" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "https://github.com/wwayne/redux-reset" 14 | }, 15 | "keywords": [ 16 | "redux", 17 | "react", 18 | "redux enhancer", 19 | "redux store enhancer", 20 | "js", 21 | "javascript", 22 | "redux component", 23 | "reset state" 24 | ], 25 | "standard": { 26 | "parser": "babel-eslint", 27 | "ignore": [ 28 | "lib/" 29 | ] 30 | }, 31 | "engines": { 32 | "node": ">=4.2.1" 33 | }, 34 | "bugs": { 35 | "url": "https://github.com/wwayne/redux-reset/issues" 36 | }, 37 | "homepage": "https://github.com/wwayne/redux-reset", 38 | "author": "wwayne", 39 | "license": "MIT", 40 | "devDependencies": { 41 | "babel-cli": "^6.6.5", 42 | "babel-eslint": "^6.0.0", 43 | "babel-preset-es2015": "^6.6.0", 44 | "babel-register": "^6.7.2", 45 | "es6-enum": "^1.0.0", 46 | "redux": "^3.3.1", 47 | "redux-thunk": "^2.0.1", 48 | "snazzy": "^3.0.0", 49 | "standard": "^6.0.8", 50 | "tap-spec": "^4.1.1", 51 | "tape": "^4.5.1" 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | export default function resetMiddleware (option) { 2 | return (next) => (reducer, initialState, enhancer) => { 3 | let resetType = 'RESET' 4 | let resetData = 'state' 5 | 6 | if ((typeof option === 'string' && option.length > 0) || typeof option === 'symbol') { 7 | resetType = option 8 | } else if (typeof option === 'object') { 9 | resetType = typeof option.type === 'string' && option.type.length > 0 || typeof option === 'symbol' ? option.type : resetType 10 | resetData = typeof option.data === 'string' && option.data.length > 0 ? option.data : resetData 11 | } 12 | 13 | const enhanceReducer = (state, action) => { 14 | if (action.type === resetType) { 15 | state = action[resetData] 16 | } 17 | return reducer(state, action) 18 | } 19 | 20 | return next(enhanceReducer, initialState, enhancer) 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /test/index.test.js: -------------------------------------------------------------------------------- 1 | import test from 'tape' 2 | import Enum from 'es6-enum' 3 | import {createStore, compose, combineReducers, applyMiddleware} from 'redux' 4 | import thunk from 'redux-thunk' 5 | import reduxReset from '../src' 6 | 7 | let initState 8 | let reducers 9 | const APP = Enum('RESET') 10 | 11 | const before = test 12 | before('Setup', (t) => { 13 | // Initial state in app reducer 14 | initState = { 15 | isLogin: false, 16 | user: {} 17 | } 18 | // Reducers 19 | const app = (state = initState, action) => { 20 | switch (action.type) { 21 | case 'LOGIN': 22 | return { 23 | isLogin: true, 24 | user: { 25 | token: 'test' 26 | } 27 | } 28 | default: 29 | return state 30 | } 31 | } 32 | reducers = combineReducers({app}) 33 | t.end() 34 | }) 35 | 36 | test('Should rest success if use default reset action', (t) => { 37 | const enHanceCreateStore = reduxReset()(createStore) 38 | const store = enHanceCreateStore(reducers) 39 | 40 | store.dispatch({ type: 'LOGIN' }) 41 | store.dispatch({ type: 'RESET' }) 42 | t.deepEqual(store.getState(), { 43 | app: initState 44 | }) 45 | t.end() 46 | }) 47 | 48 | test('Should rest success if use custom reset action', (t) => { 49 | const enHanceCreateStore = reduxReset(APP.RESET)(createStore) 50 | const store = enHanceCreateStore(reducers) 51 | 52 | store.dispatch({ type: 'LOGIN' }) 53 | store.dispatch({ type: APP.RESET }) 54 | t.deepEqual(store.getState(), { 55 | app: initState 56 | }) 57 | t.end() 58 | }) 59 | 60 | test('Should works well with other store enhancer like applyMiddleware', (t) => { 61 | const enHanceCreateStore = compose( 62 | applyMiddleware(thunk), 63 | reduxReset(APP.RESET) 64 | )(createStore) 65 | const store = enHanceCreateStore(reducers) 66 | 67 | store.dispatch({ type: 'LOGIN' }) 68 | store.dispatch({ type: APP.RESET }) 69 | t.deepEqual(store.getState(), { 70 | app: initState 71 | }) 72 | t.end() 73 | }) 74 | 75 | test('Should rest to specific state when trigger reset', (t) => { 76 | const enHanceCreateStore = reduxReset(APP.RESET)(createStore) 77 | const store = enHanceCreateStore(reducers) 78 | const newState = {app: {test: 'test'}} 79 | 80 | store.dispatch({ type: 'LOGIN' }) 81 | store.dispatch({ 82 | type: APP.RESET, 83 | state: newState 84 | }) 85 | t.deepEqual(store.getState(), newState) 86 | t.end() 87 | }) 88 | 89 | test('Should rest to specific state when giving a specific state params', (t) => { 90 | const enHanceCreateStore = reduxReset({data: 'data'})(createStore) 91 | const store = enHanceCreateStore(reducers) 92 | const newState = {app: {test: 'test'}} 93 | 94 | store.dispatch({ type: 'LOGIN' }) 95 | store.dispatch({ 96 | type: 'RESET', 97 | data: newState 98 | }) 99 | t.deepEqual(store.getState(), newState) 100 | t.end() 101 | }) 102 | 103 | test('Should rest to specific state when giving a specific state params and action type', (t) => { 104 | const enHanceCreateStore = reduxReset({type: 'TEST', data: 'initialStateComesFrom'})(createStore) 105 | const store = enHanceCreateStore(reducers) 106 | const newState = {app: {test: 'test'}} 107 | 108 | store.dispatch({ type: 'LOGIN' }) 109 | store.dispatch({ 110 | type: 'TEST', 111 | initialStateComesFrom: newState 112 | }) 113 | t.deepEqual(store.getState(), newState) 114 | t.end() 115 | }) 116 | 117 | --------------------------------------------------------------------------------