Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/alixander/redux-store-validator
Add validation to your Redux reducers
https://github.com/alixander/redux-store-validator
javascript react redux
Last synced: about 1 month ago
JSON representation
Add validation to your Redux reducers
- Host: GitHub
- URL: https://github.com/alixander/redux-store-validator
- Owner: alixander
- License: mit
- Archived: true
- Created: 2017-02-11T19:19:52.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2017-02-19T02:18:32.000Z (over 7 years ago)
- Last Synced: 2024-09-25T15:05:19.964Z (about 1 month ago)
- Topics: javascript, react, redux
- Language: JavaScript
- Homepage:
- Size: 8.79 KB
- Stars: 26
- Watchers: 4
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
Redux Store Validator
=========
![travis-badge](https://travis-ci.org/alixander/redux-store-validator.svg?branch=master)Wrapper to add validation to your Redux reducers
```
npm install --save redux-store-validator
```### Purpose
In a large React/Redux app, the store can become intractable. A common cause of bugs is when the data in the store has changed in a way that the developer didn't expect. `redux-store-validator` is intended to facilitate adding detection of when such a scenario occurs. You can add as many or as little validators to specific parts of your store, and act on it accordingly. For example, you can add a validator to check that a value which you expected to be always positive ever becomes negative. If so, you can log or recover right after the offending action modifies the store.
### Usage
Wrap your reducers
#### reducers/index.js
```js
import { withValidation } from 'redux-store-validator';import aReducer, { validator as aValidator } from './a';
import { bReducer } from './b';const reducers = {
a: aReducer,
b: bReducer
}const validators = {
// Only add validators for substates you want validation on
a: aValidator
}// Instead of
// const rootReducer = combineReducers(reducers);
// You wrap your reducers in 'withValidation' and pass in the validators to execute
const rootReducer = combineReducers(withValidation(reducers, validators));
```Add validators to reducers as needed
#### reducers/a.js
```js
export function validator(state) {
return state.word === 'asdf';
}export default function(state, action) {
switch(action.type) {
case 'asdf':
state.word = 'asdf';
return state;
default:
return state;
}
}
```That's it. After you've wrapped your reducers and added validators, you can detect if the store has become invalid by querying the state.
`redux-store-validator` adds the following to your redux state:
`state[INVALID_KEYS]`: Array of keys which correspond to the substates that are invalid.
You can act upon it however you like. Below are just a few examples
## Examples of acting upon invalid store
In your component you can choose not to render with the new data if it's invalid.
### components/myComponent.jsx
```js
import { INVALID_KEYS } from 'redux-store-validator';
...const myComponent = React.createClass({
props: {
text: PropTypes.string,
isValid: PropTypes.bool
},shouldComponentUpdate(nextProps) {
return nextProps.isValid;
},...
render() {
return{this.props.text};
}
});function mapStateToProps(state) {
return {
text: state.a.word,
isValid: state[INVALID_KEYS].includes('a')
}
}
...
```---------------------------
You can replace the state with a default valid one as soon as an action caused it to become invalid.
#### Back in reducers/index.js
```js
import aReducer, {
validator as aValidator,
defaultState as aDefaultState
} from './a';
import { bReducer } from './b';import { INVALID_KEYS } from 'redux-store-validator';
const reducers = {
a: aReducer,
b: bReducer
}const validators = {
// Only add validators for substates you want validation on
a: aValidator
}const defaultStates = {
a: aDefaultState
}const rootReducer = combineReducers(withValidation(reducers, validators));
function replaceInvalid(combinedReducer) {
return (state, action) => {
const newState = combinedReducer(state, action);
if (newState.INVALID_KEYS.length === 0) {
return newState;
}
for (const validatedSubstate of Object.keys(validators)) {
if (newState[INVALID_KEYS].includes(validatedSubstate)) {
newState[validatedSubstate] = defaultStates[validatedSubstate]
// If the default state is valid, the INVALID_KEYS will remove the state key in the next reduction step
}
}
return newState;
}
}
export default replaceInvalid(rootReducer);
```---------------------------
You can log in a logger middleware
#### middlewares/Logger.js
```js
import { INVALID_KEYS } from 'redux-store-validator';export default ({getState}) => (next) => (action) => {
const state = getState();
if (state[INVALID_KEYS].length !== 0) {
// Log the invalid states
for (const key of state[INVALID_KEYS]) {
const substate = state[key];
...
}
...
}
...
return next(action);
}
```