Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

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
Appearance settings

Commitd8b8541

Browse files
committed
make verison of redux-machine for use with immutable-js
1 parentd702155 commitd8b8541

File tree

5 files changed

+83
-83
lines changed

5 files changed

+83
-83
lines changed

‎README.md‎

Lines changed: 20 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,9 @@
22

33
![redux-machine](http://i63.tinypic.com/2igdbus_th.jpg)
44

5-
*A tiny lib (12 lines) for creating state machines as swappable Redux reducers*
5+
*A tiny lib (16 lines) for creating state machines as swappable Redux reducers*
6+
7+
>This is the version of this library to use when your Redux store state is an[Immutable JS](https://facebook.github.io/immutable-js/)[Map](https://facebook.github.io/immutable-js/docs/#/Map). See also the[non-immutable-js version of redux-machine](https://github.com/mheiber/redux-machine).
68
79
redux-machine enables you to create[reducers](http://redux.js.org/docs/basics/Reducers.html) that can transition between different "statuses." These are likes states in a[finite state machine](https://en.wikipedia.org/wiki/Finite-state_machine). The goal is for redux-machine to support complex workflows simply while keeping all state in the redux store. Keeping all state in the store is good because:
810

@@ -38,10 +40,9 @@ The reducer returned by `createMachine` will act like `initReducer` when its sta
3840
constinitReducer= (state= {error:null, users: []},action)=> {
3941
switch (action.type) {
4042
case'FETCH_USERS':
41-
returnObject.assign({}, state, {
42-
error:null,
43-
// transition to a different status!
44-
status:'IN_PROGRESS'
43+
return state
44+
.set('error',null)
45+
.set('status','IN_PROGRESS')
4546
})
4647
default:
4748
return state
@@ -51,18 +52,19 @@ const initReducer = (state = {error: null, users: []}, action) => {
5152
constinProgressReducer= (state= {},action)=> {
5253
switch (action.type) {
5354
case'FETCH_USERS_RESPONSE':
54-
returnObject.assign({}, state, {
55-
error:null,
56-
users:action.payload.users,
57-
// transition to a different status!
58-
status:'INIT'
55+
returnstate.withMutations(map=> {
56+
return map
57+
.set('error',null)
58+
.set('users',action.payload.users)
59+
.set('status','INIT')
5960
})
6061
case'FETCH_USERS_FAIL':
61-
returnObject.assign({}, state, {
62-
error:action.payload.error,
63-
// transition to a different status!
64-
status:'INIT'
65-
})
62+
return state
63+
.set('error',action.payload.error)
64+
.set('status','INIT')
65+
return state
66+
.set('error',action.payload.error)
67+
.set('status','INIT')
6668
default:
6769
return state
6870
}
@@ -83,7 +85,7 @@ You don't need redux-machine, since you can accomplish almost the same thing as
8385

8486
```js
8587
constfetchUsersReducer= (state,action)=> {
86-
switch (state.status) {
88+
switch (state.get(status)) {
8789
case'INIT':
8890
returninitReducer(state, action)
8991
case'IN_PROGRESS':
@@ -96,44 +98,10 @@ const fetchUsersReducer = (state, action) => {
9698

9799
The (marginal) advantages of using redux-machine over just using the FSM pattern is that you can more clearly express intent and write slightly less code.
98100

99-
##Asynchronous Effects
100-
101-
redux-machine doesn't prescribe a way of handling asynchronous effects such as API calls. This leaves it open for you to use[no async effects library](http://stackoverflow.com/a/34599594/2482570),[redux-loop](https://github.com/redux-loop/redux-loop),[redux-thunk](https://github.com/gaearon/redux-thunk),[redux-saga](https://github.com/yelouafi/redux-saga), or anything else.
102-
103-
That said, redux-machine fits very naturally with other tools which enhance the expressiveness of reducers, such as redux-loop and redux-side-effect. Here's how you could use redux-machine with redux-loop:
104-
105-
```js
106-
import {loop,Effects }from'redux-loop'
107-
import {apiFetchUsers }from'../api'
108-
109-
constgetUsers= ()=>apiFetchUsers.then(users=> ({
110-
type:'FETCH_USERS_RESPONSE',
111-
payload: { users }
112-
}))
113-
114-
constinitReducer= (state= {error:null, users: []},action)=> {
115-
116-
switch (action.type) {
117-
case'FETCH_USERS':
118-
returnloop(
119-
// return the next state of the store
120-
// and transition to the IN_PROGRESS status
121-
Object.assign({}, state, {error:null, status:'IN_PROGRESS'}),
122-
// pass getUsers to the redux-loop middleware
123-
// The redux-loop middleware will call getUsers(), which
124-
// will dispatch a 'FETCH_USERS_RESPONSE' action
125-
Effects.promise(getUsers)
126-
)
127-
default:
128-
return state
129-
}
130-
}
131-
132-
133-
```
134-
135101
##Examples
136102

137103
[Cancellable Counter](https://github.com/mheiber/redux-funk-examples)
138104

139105
[Shopping Cart](https://github.com/mheiber/redux-funk-examples)
106+
107+
>These examples use the[non-immutable-js version](https://github.com/mheiber/redux-machine) of redux-machine.

‎index.js‎

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,19 @@
22

33
varcreateMachine=function(reducersObject){
44
returnfunction(state,action){
5-
varstatus=(state&&state.status) ?state.status :'INIT'
5+
if(!state.get||!state.set){
6+
thrownewError(
7+
'Expected state to be an ImmutableJS Map.'
8+
+' If your state is a plain JS object, use redux-machine instead')
9+
}
10+
varstatus=(state&&state.get('status')) ?state.get('status') :'INIT'
611
varreducer=reducersObject[status]
712
if(!reducer){
813
thrownewError('reducersObject missing reducer for status '+status)
914
}
1015
constnextState=reducer(state,action)
11-
returnObject.assign({},nextState,{'status':nextState.status||status})
16+
returnnextState.set('status',nextState.get('status')||status)
1217
}
1318
}
1419

15-
module.exports={createMachine:createMachine,become:'status'/* for backwards compatibility */}
20+
module.exports={createMachine:createMachine}

‎package.json‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,11 @@
2424
"homepage":"https://github.com/mheiber/redux-machine#readme",
2525
"devDependencies": {
2626
"faucet":"^0.0.1",
27+
"immutable":"^3.8.1",
2728
"redux":"^3.6.0",
2829
"tape":"^4.6.2"
30+
},
31+
"dependencies": {
32+
"immutable":"^3.8.1"
2933
}
3034
}

‎test.js‎

Lines changed: 47 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -3,37 +3,37 @@
33
const{ createStore}=require('redux')
44
consttest=require('tape')
55
const{ createMachine}=require('./index.js')
6+
const{ Map, List}=require('immutable')
67

78
// BEGIN FIXTURES
89

9-
constusers=['userFoo','userBar','userBaz']
10+
constusers=List(['userFoo','userBar','userBaz'])
1011

11-
constinitReducer=(state={},action)=>{
12+
constinitReducer=(state=Map(),action)=>{
1213
switch(action.type){
1314
case'FETCH_USERS':
14-
returnObject.assign({},state,{
15-
error:null,
16-
status:'IN_PROGRESS'
17-
})
15+
returnstate
16+
.set('error',null)
17+
.set('status','IN_PROGRESS')
1818
default:
1919
returnstate
2020
}
2121
}
2222

23-
constinProgressReducer=(state={},action)=>{
23+
constinProgressReducer=(state=Map(),action)=>{
2424

2525
switch(action.type){
2626
case'FETCH_USERS_RESPONSE':
27-
returnObject.assign({},state,{
28-
error:null,
29-
users:action.payload.users,
30-
status:'INIT'
27+
returnstate.withMutations(map=>{
28+
map
29+
.set('error',null)
30+
.set('users',action.payload.users)
31+
.set('status','INIT')
3132
})
3233
case'FETCH_USERS_FAIL':
33-
returnObject.assign({},state,{
34-
error:action.payload,
35-
status:'INIT'
36-
})
34+
returnstate
35+
.set('error',action.payload)
36+
.set('status','INIT')
3737
default:
3838
returnstate
3939
}
@@ -51,11 +51,11 @@ const fetchUsersReducer = createMachine({
5151

5252
test('should transition between states',t=>{
5353

54-
letstate=undefined
54+
letstate=Map()
5555
letprevState=undefined
5656
conststore=createStore(fetchUsersReducer,state)
5757

58-
constexpectState=(expected,maybeMessage)=>t.deepEquals(state,expected,maybeMessage)
58+
constexpectState=(expected,maybeMessage)=>t.deepEquals(state.toJS(),expected.toJS(),maybeMessage)
5959

6060
constaction=(type,payload)=>{
6161
prevState=state
@@ -64,46 +64,46 @@ test('should transition between states', t => {
6464
}
6565

6666
action('DUMMY')
67-
expectState({
67+
expectState(Map({
6868
status:'INIT',
69-
},'Should set initial status to "INIT"')
69+
}),'Should set initial status to "INIT"')
7070

7171
action('FETCH_USERS_RESPONSE',{users})
7272
expectState(prevState,'Should ignore messages when not handled by current status')
7373

7474
action('FETCH_USERS')
75-
expectState({
75+
expectState(Map({
7676
error:null,
7777
status:'IN_PROGRESS'
78-
})
78+
}))
7979

8080
action('FETCH_USERS_FAIL','timeout')
81-
expectState({
81+
expectState(Map({
8282
error:'timeout',
8383
status:'INIT'
84-
})
84+
}))
8585

8686
action('FETCH_USERS')
87-
expectState({
87+
expectState(Map({
8888
error:null,
8989
status:'IN_PROGRESS'
90-
})
90+
}))
9191

9292
action('FETCH_USERS')
9393
expectState(prevState)
9494

9595
action('FETCH_USERS_RESPONSE',{users})
96-
expectState({
96+
expectState(Map({
9797
error:null,
9898
status:'INIT',
9999
users
100-
})
100+
}))
101101

102102
t.end()
103103
})
104104

105105
test('should error on status not found',t=>{
106-
letstore={status:'STATUS_NOT_IN_CREATE_MACHINE'}
106+
letstore=Map({status:'STATUS_NOT_IN_CREATE_MACHINE'})
107107
constreducer=createMachine({})
108108
leterror
109109
try{
@@ -120,3 +120,22 @@ test('should error on status not found', t => {
120120

121121
t.end()
122122
})
123+
124+
test('should error when plain JS object used for state',t=>{
125+
leterror
126+
constreducer=createMachine({})
127+
try{
128+
reducer({},{type:'DUMMY'})
129+
}
130+
catch(err){
131+
error=err
132+
}
133+
134+
t.equals(
135+
error.message,
136+
'Expected state to be an ImmutableJS Map.'
137+
+' If your state is a plain JS object, use redux-machine instead'
138+
)
139+
140+
t.end()
141+
})

‎yarn.lock‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,10 @@ has@~1.0.1:
104104
dependencies:
105105
function-bind "^1.0.2"
106106

107+
immutable:
108+
version "3.8.1"
109+
resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.8.1.tgz#200807f11ab0f72710ea485542de088075f68cd2"
110+
107111
inflight@^1.0.4:
108112
version "1.0.6"
109113
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp