├── .babelrc ├── .eslintignore ├── .gitignore ├── .npmignore ├── README.md ├── package.json ├── src ├── index.js └── reset.js └── test ├── index.js └── resetSpec.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": ["env"] 3 | } 4 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | dist 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | coverage 4 | dist 5 | .idea/ 6 | yarn.lock 7 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | src 2 | test 3 | coverage 4 | resources 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # redux-reset-store 2 | Higher Order Reducer for resetting multiple parts of your state tree 3 | 4 | [![npm version](https://badge.fury.io/js/redux-reset-store.svg)](https://badge.fury.io/js/redux-reset-store) 5 | [![Get on Slack](http://slack.apollostack.com/badge.svg)](http://slack.apollostack.com/) 6 | 7 | Wrap any of your Reducers with this higher order reducer to clear state when a certain action is dispatched. 8 | 9 | ### `composeResetReducer(reducerFn, initialState, resetType)` 10 | 11 | #### Arguments 12 | 13 | 1. `reducer` *(Function)*: A reducing function that returns the next state tree given the current state tree and an action to handle. 14 | 15 | 2. [`initialState`] *(any)*: The initial state. This is the value you want to reset the state to when the preferred action type is dispatched 16 | 17 | 3. [`resetType`] *(string)*: Preferred Action Type to trigger reset in state. Default is `"RESET_STATE"` 18 | 19 | 20 | 21 | ### Example 22 | 23 | ```js 24 | import { composeResetReducer } from 'redux-reset-store'; 25 | import { store } from './store'; 26 | 27 | // current state after init = false 28 | const toggleReducer = composeResetReducer(function toggleReducer(state = false, action = {}) { 29 | if (action.type === 'TOGGLE') { 30 | return true; 31 | } 32 | return state; 33 | }, false); 34 | 35 | export default toggleReducer 36 | 37 | // Default action type is RESET_STATE 38 | store.dispatch({type: "TOGGLE"}); 39 | 40 | // current state after toggle = true 41 | store.dispatch({type: "RESET_STATE"}); 42 | // current state after reset = false 43 | ``` 44 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "redux-reset-store", 3 | "version": "1.0.1", 4 | "description": "Higher Order Reducer for resetting multiple parts of your state tree", 5 | "main": "dist/index.js", 6 | "directories": { 7 | "test": "test" 8 | }, 9 | "scripts": { 10 | "prepublish": "npm run build", 11 | "build": "babel ./src --ignore test --out-dir ./dist", 12 | "test": "mocha --require babel-core/register ./test", 13 | "lint": "eslint ." 14 | }, 15 | "devDependencies": { 16 | "babel-cli": "^6.6.5", 17 | "babel-core": "6.26.0", 18 | "babel-eslint": "^8.0.2", 19 | "babel-preset-env": "^1.6.1", 20 | "chai": "^4.1.2", 21 | "eslint": "^4.11.0", 22 | "eslint-config-airbnb": "^16.1.0", 23 | "eslint-plugin-import": "^2.8.0", 24 | "mocha": "^4.0.1", 25 | "redux": "^3.5.2" 26 | }, 27 | "repository": { 28 | "type": "git", 29 | "url": "git+https://github.com/abhiaiyer91/redux-reset.git" 30 | }, 31 | "eslintConfig": { 32 | "parser": "babel-eslint", 33 | "extends": [ 34 | "airbnb/base", 35 | "plugin:import/errors" 36 | ], 37 | "rules": { 38 | "no-use-before-define": 0, 39 | "arrow-body-style": 0, 40 | "dot-notation": 0, 41 | "no-console": 0 42 | }, 43 | "env": { 44 | "mocha": true 45 | } 46 | }, 47 | "keywords": [ 48 | "redux", 49 | "react", 50 | "Javascript", 51 | "reset" 52 | ], 53 | "author": "Abhi Aiyer", 54 | "license": "ISC" 55 | } 56 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | export { composeResetReducer, DEFAULT_RESET_TYPE } from './reset'; 2 | -------------------------------------------------------------------------------- /src/reset.js: -------------------------------------------------------------------------------- 1 | export const DEFAULT_RESET_TYPE = 'RESET_STATE'; 2 | /** 3 | * Add a reset to store state for given reducer 4 | * @param reducer 5 | * @param initialState - value we are resetting to 6 | * @param resetType - override default reset type 7 | * @returns composedReducer - Higher order function 8 | */ 9 | export const composeResetReducer = function composeResetReducer(reducer, initialState, resetType) { 10 | const resetActionType = resetType || DEFAULT_RESET_TYPE; 11 | return function composedReducer(state, action) { 12 | let newState = state; 13 | if (action.type === resetActionType) { 14 | newState = initialState; 15 | } 16 | return reducer(newState, action); 17 | }; 18 | }; 19 | -------------------------------------------------------------------------------- /test/index.js: -------------------------------------------------------------------------------- 1 | import './resetSpec'; 2 | -------------------------------------------------------------------------------- /test/resetSpec.js: -------------------------------------------------------------------------------- 1 | import { assert } from 'chai'; 2 | import { createStore, combineReducers } from 'redux'; 3 | import { composeResetReducer, DEFAULT_RESET_TYPE } from '../src/reset'; 4 | 5 | function toggleState(store) { 6 | return store.dispatch({ 7 | type: 'TOGGLE', 8 | }); 9 | } 10 | 11 | function resetState(type, store) { 12 | return store.dispatch({ 13 | type, 14 | }); 15 | } 16 | 17 | function testReducer(state = false, action) { 18 | if (action.type === 'TOGGLE') { 19 | return true; 20 | } 21 | return state; 22 | } 23 | 24 | describe('Reset Reducer', () => { 25 | it('should reset state of the reducer', () => { 26 | const rootReducer = combineReducers({ 27 | test: composeResetReducer(testReducer, false), 28 | }); 29 | const store = createStore(rootReducer); 30 | // toggle the state 31 | toggleState(store); 32 | // reset 33 | resetState(DEFAULT_RESET_TYPE, store); 34 | assert.equal(store.getState().test, false); 35 | }); 36 | 37 | it('should reset state with custom acton type', () => { 38 | const testType = 'RESET_TEST_STATE'; 39 | const rootReducer = combineReducers({ 40 | test: composeResetReducer(testReducer, false, testType), 41 | }); 42 | const store = createStore(rootReducer); 43 | // toggle the state 44 | toggleState(store); 45 | // reset 46 | resetState(testType, store); 47 | assert.equal(store.getState().test, false); 48 | }); 49 | 50 | it('should reset state with initialStates', () => { 51 | const rootReducer = composeResetReducer( 52 | combineReducers({ 53 | test: testReducer, 54 | test2: testReducer, 55 | }), 56 | { test2: true }, 57 | ); 58 | 59 | const store = createStore(rootReducer); 60 | // toggle the state 61 | toggleState(store); 62 | // reset 63 | resetState(DEFAULT_RESET_TYPE, store); 64 | assert.equal(store.getState().test, false); 65 | assert.equal(store.getState().test2, true); 66 | }); 67 | }); 68 | --------------------------------------------------------------------------------