- single store modified via actions
- tiny api - easy to understand, easy to adapt
- tiny size - 1KB
- react and preact bindings included
- react and preact debug mode for identifying re-renders
- beautiful console logger
- redux devtools integration
How is this different from redux? The key differences are:
- actions in tiny-atom can read and update the state and dispatch other actions. Actions are self contained units of business logic. This removes layers of boilerplate while preserving the benefits of redux like stores.
- tiny-atom includes useful utilities to make it completely sufficient for building application of any size.
$ npm install tiny-atom
Read the full docs or pick one of the highlights:
const createAtom = require('tiny-atom')
const atom = createAtom({ unicorns: 0, rainbows: [] }, {
incrementUnicorns ({ get, set }, n) {
set({ unicorns: get().unicorns + n })
},
async fetchRainbows ({ set, dispatch }) {
set({ loading: true })
const { data: rainbows } = await axios.get('/api/rainbows')
set({ rainbows, loading: false })
dispatch('incrementUnicorns', 1)
}
})
atom.observe((atom) => {
console.log('atom', atom)
const { rainbows, unicorns } = atom.get()
render(unicorns).onClick(e => atom.dispatch('incrementUnicorns', 10))
})
Create an atom.
type: any
default: {}
The initial state of the atom. If custom data structure is used (e.g. Immutable), make sure to also specify an appropriate options.merge
implementation.
type: object
default: {}
An object with action functions. The signature of an action function is ({ get, set, dispatch }, payload)
. If you provide nested action objects or other structure, make sure to also specify an appropriate options.evolve
implementation to handle your actions appropriately.
get()
- returns the current stateset(patch, options)
- updates the state with the patch object by merging the patch usingoptions.merge
function. The default implementation is deep merge. Use{ replace: true }
option to replace the state instead of merging in the patch.dispatch
- same asatom.dispatch
, dispatches an action.
type: function
A function called on each set(update)
to merge the update into the state. The function signature is (state, update) => state'
. The default implementation is a deep merge.
type: function
A function that receives all of the dispatched action objects and calls the action functions. The function signature is (atom, action, actions)
. Note that atom
in this place has an extra added function set
, a function that is used to update the state, this function does not exist on the actual atom. The default implementation uses action.type
to find the matching function in the actions
object.
type: function | function[]
default: null
A function that will be called on each action and state update. The function is passed an info
object of shape { type, atom, action, sourceActions, prevState }
. Tiny atom comes with 2 built in debug functions tiny-atom/log
and tiny-atom/devtools
.
createAtom({ count: 1 }, {
increment: ({ get, set }, payload) => set({ count: get().count + payload }),
inc: ({ dispatch }, payload) => dispatch('increment', payload)
})
Get current state.
atom.get()
atom.get().feed.items
Send an action
atom.dispatch('fetchMovies')
atom.dispatch('increment', 5)
Register a callback for when atom changes. Returns the unobserve function.
atom.observe(render)
atom.observe(atom => render(atom.get(), atom.dispatch))
Extend atom's state and the action object. Convenient for composing atom from slices of state and actions from several modules.
const state = {
project: { name: 'tiny-atom' }
}
const actions = {
star: ({ get, set }) => set({
project: { starred: true }
})
}
atom.fuse(state, actions)
For documentation on the set of react and preact components <Provider />
, <Consumer />
and connect
see react or preact docs.