Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up

Tiny flux implementation built on mitt

License

NotificationsYou must be signed in to change notification settings

tkh44/smitty

Repository files navigation

smitty
smitty

Tiny flux implementation built onmitt

smitty

npm versionBuild Statuscodecov

Install

npm install -S smitty

Basic Usage

import{createStore}from'smitty'// Create a store with initial stateconstinitialState={count:0}conststore=createStore(initialState)store.createActions({add:'count/ADD'})// add a reducerstore.handleActions({[store.actions.add]:(state,e,type)=>{// increment foos by amountreturnObject.assign({},state,{count:state.count+e.amount})},'*':(state,e,type)=>{// '*' can be used for all kinds of fun stuffconsole.log(e,type)if(type==='count/ADD'){//...do something}returnstate}})store.actions.add({amount:5})console.log(store.state)// logs `{ count: 5 }`

Demos (v2)

Demos (v1)


Usage with Preact and React


API

createStore(initialState: any)

Arguments

initialState: anyrequired: Determines the shape and initial state of your store. Can be of any type that you choose.

Returns

Store: StoreStore


Store

emit: (function)

arguments

type: (string |function)

  • [string],type determines which reducers are called.

    conststore=createStore(0)store.handleActions({add:function(state,payload){returnstate+payload}})console.log(store.state)// logs 0store.emit('add',1)console.log(store.state)// logs 1
  • [function]type becomes an action creator that is passed 1 argument

    This is useful to emit multiple actions from a single emit call.

    conststore=createStore(0)store.handleActions({add:function(state,payload){returnstate+payload}})functionasyncAction(emit,state){emit('add',1)console.log(state)// logs 1setTimeout(()=>{emit('add',1)console.log(state)// logs 3},100)emit('add',1)console.log(state)// logs 2}```

payload: (any) optional

payload to pass to your reducer

conststore=createStore({name:'Arrow'})store.handleActions({'update/NAME':function(state,payload){// I really don't care if you return a new state// Nobody is judging. Do what your ❤️ tells you.// Just be consistentreturnObject.assign({},state,payload)}})console.log(store.state)// logs { name: 'Arrow' }store.emit('update/NAME',{name:'River'})console.log(store.state)// logs { name: 'River' }

createActions(): (function)

arguments

actionMap: (object)

Object where key is the action creator's name and the value can be of typestring orfunction.

If the value is astring, an action creator is attached tostore.actions as a function that accepts one argument,payload.

store.createActions({add:'count/ADD'})// The following are functionally equivalentstore.actions.add(1)store.emit('count/ADD',1)

Action creators with a string value can be used as the key in youractionMap inhandleActions.

store.createActions({add:'count/ADD'})// add a reducerstore.handleActions({[store.actions.add]:(state,e,type)=>{// increment foos by amountreturnObject.assign({},state,{count:state.count+e.amount})}})store.actions.add({amount:5})console.log(store.state)// logs `{ count: 5 }`

If the value is afunction, it must be a function that returns an action creator. For async action creators.

store.createActions({add:(amount)=>{return(store)=>{setTimeout(()=>{store.emit('count/ADD',amount)},16)}}})store.actions.add(1)

handleActions(): (function)

arguments

handlerMap: (object)

Object with keys that correspond to action types passed toemit

When an event is emitted and the key matches the type the reducer is invoked with 3 arguments.

  • state: (any) the store's state getter
  • payload (any) the payload that was emitted
  • type (string) the type that was emitted
conststore=createStore({color:'blue',hovered:false})store.handleActions({'merge':function(state,payload){returnObject.assign({},state,payload)},'overwrite':function(state,payload){returnpayload},// Could do the same in one// If you really miss redux do this and put a switch statement'*':function(state,payload,type){returntype==='merge' ?Object.assign({},state,payload) :payload}})console.log(store.state)// logs { color: 'blue', hovered: false }store.emit('merge',{color:'red'})console.log(store.state)// { color: 'red', hovered: false }store.emit('overwrite',{color:'green',hovered:true,highlighted:false})console.log(store.state)// { color: 'green', hovered: true, highlighted: false

actions: (object)

Map of all the actions created instore.createActions

This is convenient so that you do not have to deal with action imports across your app.

on: (function)

Convenience shortcut formitt.on.

off: (function)

Convenience shortcut formitt.off.


Action Creator Detailed Example

You can pass a function toemit in order to create an action creator

running example

import{createStore}from'smitty'// Create a store with initial stateconstinitialState={}conststore=createStore(initialState)// add our reducerstore.handleActions({'api/GET_ROOM':(state,{ id, res})=>{return{      ...state,[id]:{        ...state[id],        ...res.data}}}})// create our action creatorsconstactions={requestRoom(id){returnasync(emit,state)=>{emit('REQUEST_ROOM',{ id,res:{data:{ id}}})constres=awaitwindow.fetch(`https://api.mysite.com/${id}`)res.data=awaitres.json()emit('REQUEST_ROOM',{ id, res})}}}// When calling emit with a function argument, the function will be called with `emit` and `state` as argumentsconstresult=store.emit(actions.requestRoom('1a'))// Return whatever you like from your action creatorconsole.log(result)// logs "Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}"// After the fetch call, `REQUEST_ROOM` is fired a second time with our response dataresult.then(()=>console.log(store.state))// logs `{ 1a: { id: '1a', title: 'My Room' }``

Class As Reducer

Reducers are iterated withfor (let type in reducer) {...} with noobj.hasOwnProperty check so this works.

conststore=createStore({foo:5})classHistoryReducer{constructor(initialHistory=[]){this.history=createStore(initialHistory)this.history.handleActions({update:(state,e)=>{state.push(e)}})}onUpdate(state,e,type){this.history.emit('update',{ state, e, type})}}HistoryReducer.prototype['foo/ADD']=function(state,e,type){state.foo+=e.foothis.onUpdate(state,e,type)}consthistoryReducer=newHistoryReducer([])store.handleActions(historyReducer)store.emit('foo/ADD',{foo:5})console.log(store.state.foo)// logs 10store.emit('foo/ADD',{foo:7})console.log(store.state.foo)// logs 17console.log(historyReducer.history.state)// logs// [//   { state: { foo: 10 }, e: { foo: 5 }, type: 'foo/ADD'},//   { state: { foo: 17 }, e: { foo: 7 }, type: 'foo/ADD'}// ]

Thanks

Thanks todevelopit formitt and the project structure.


[8]ページ先頭

©2009-2025 Movatter.jp