Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/baccigalupi/redaxted
Tools for redacting the noise of Redux
https://github.com/baccigalupi/redaxted
Last synced: about 1 month ago
JSON representation
Tools for redacting the noise of Redux
- Host: GitHub
- URL: https://github.com/baccigalupi/redaxted
- Owner: baccigalupi
- License: mit
- Created: 2020-10-18T17:48:09.000Z (about 4 years ago)
- Default Branch: main
- Last Pushed: 2022-01-23T17:18:28.000Z (almost 3 years ago)
- Last Synced: 2024-04-26T01:04:25.177Z (8 months ago)
- Language: JavaScript
- Size: 59.6 KB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
# redaxted
Tools for redacting the noise of [Redux](https://github.com/reduxjs/redux).
## Motivation
Redux is an amazing tool for thinking of complex data in terms of small
transformations!However, projects that use redux can fail to smooth out norms, and often end
devolve into gigantic, ugly case statements that are hard to maintain. The
creators of Redux have recognized this and built some tools for smoothing out
these rough edges, but they are not particularly readable. They provide the kind
of API that requires memorization and consistent use.This is a series of small tested tools that let you:
* Not thing about creating constants
* Normalize the payload of an action
* Create reducers declaratively focused on a single action type
* Compose reducers for many action types related to an area of the store## Usage
### Creating actions
Instead of generating a bunch of constants and then associating those with
actions, the library assumes actions don't need to be unique snowflakes, and you
don't need to know the name of the constants. You will generate actions and then
use them!```javascript
import { createActions } from 'redaxted'const actions = createActions([
'incrementCounter',
'decrementCounter',
// ... etc
])
```### Using actions
Given access to the `dispatch` function
```javascript
import actions from './path/to/actions/generated/above'const onClick = (_event) => {
disptach(actions.incrementCounter())
}
```Data passed in to the action gets normalized. There is always a `type` and a
`payload` attribute on the returned action data. The payload is a normalized
version of the value passed in. The goal of normalizing is to assure that the
payload is always an object or an array that can be easily destructured without
type checking. Here are some examples:```javascript
action.incrementCounter()
/*
{
type: 'incrementCounter',
payload: {}
}
*/action.incrementCounter(undefined)
/*
{
type: 'incrementCounter',
payload: {}
}
*/action.incrementCounter(null)
/*
{
type: 'incrementCounter',
payload: {}
}
*/action.incrementCounter({increaseBy: 10})
/*
{
type: 'incrementCounter',
payload: {increaseBy: 10}
}
*/action.incrementCounter([10])
/*
{
type: 'incrementCounter',
payload: [10]
}
*/
```Literals are packed into an object via a `value` key. Here are some examples of
that:```javascript
action.incrementCounter(false)
/*
{
type: 'incrementCounter',
payload: { value: false }
}
*/action.incrementCounter(10)
/*
{
type: 'incrementCounter',
payload: { value: 10 }
}
*/action.incrementCounter('huh?')
/*
{
type: 'incrementCounter',
payload: { value: 'huh?' }
}
*/
```These normalizations reduce the need for type systems or defensive programming.
## Creating reducers
Instead of creating massive case statements, reducers are created with simple
transformers that respond to a single action type within a single area of the
store. For a given area of the store, different type related reducers are
combined together.To create a basic action for a type use the `createReducer` and chain call
`transform` with a transformer function.Transformer functions take the form `(state, payload) => newState`.
Here is an example:
```javascript
import actions from './path/to/actions'const addReducer = createReducer(actions.addToThings)
.transform((state, payload) => [...state, payload])addReducer([], actions.addToThings('my first thing'))
// [ 'my first thing' ]
```Setting initial state is also done with a chaining call:
```javascript
import actions from './path/to/actions'const addReducer = createReducer(actions.addToThings)
.transform((state, payload) => [...state, payload.value])
.initialState([])addReducer()
// []
```### Composing reducers
Creating reducers that have a single responsibility, means that you need to
combine them via functional composition. A reducer equivalent to the gigantic
case statement is generated by passing the return values of each small reducer
to the next in line.```javascript
import actions from './path/to/actions'const addReducer = createReducer(actions.addToThings)
.transform((state, payload) => [...state, payload.value])const removeReducer = createReducer(actions.removeFromThings)
.transform((state, payload) => {
return state.filter((element) => element !== payload.value)
})const reducer = composeReducers([
addReducer,
removeReducer
])let newState = reducer([], action.addToThings('thing 1'))
// ['thing 1']
newState = reducer([], action.addToThings('thing 2'))
// ['thing 1', 'thing 2']
newState = reducer(newState, action.removeFromThings('thing 1'))
// ['thing 2']
```The `composeReducers` function also chains to allow an initial state, and of
course this initial state overrides individual state for the reducers that are
being combined:```javascript
const reducer = composeReducers([
addReducer,
removeReducer
]).initialState([])
```
### Combining reducersRedux comes out of the box with a `combineReducers` function that maps parts
of the store to a specific reducer. That usually looks like this:```javascript
const combineReducers({
users: usersReducer,
applicationStatus: statusReducers,
// ... etc
});
```That out of the box solution works most of the time and is very performant!
Occasionally Redux will complain when combining complex data/reducers. This mostly
happens when trying to coerce the sharing of data between slices of data. If
you don't run into this issue, we recommend that you continue to use Redux's version.
If it does happen to you, switch over and use this function instead!## Use with Deno
The file in `./src/index` is a good entry point for Deno work. You can include it
via this import statement:```javascript
import {
composeReducers,
createAction,
createActions,
createReducer,
} from 'https://raw.githubusercontent.com/baccigalupi/redaxted/main/mod.js';
```## Developing
This is open source. Use issues, PRs and other methods to request or suggest
changes. There is a code of conduct. Tests can be run with `yarn test`.# Building from source
The source uses es6 and so `index.js` the entry point is a Babel compiled
version of that code. You can rebuild on your branch with `yarn build`.