|
const r1 = (state, action) => { |
|
switch(action.type){ |
|
case 'add': |
|
return [...state, action.payload]; |
|
case 'remove': |
|
return [...state.filter(x => x.id !== action.payload.id)] |
|
default: |
|
return state; |
|
} |
|
} |
|
|
|
const actions = [ |
|
{ |
|
type: 'add', |
|
payload: { |
|
id: 1, |
|
name: 'james' |
|
} |
|
}, |
|
{ |
|
type: 'add', |
|
payload: { |
|
id: 2, |
|
name: 'another person' |
|
} |
|
}, |
|
{ |
|
type: 'remove', |
|
payload: { |
|
id: 1 |
|
} |
|
}, |
|
(dispatch, getState) => { |
|
fetch('https://jsonplaceholder.typicode.com/posts/1') |
|
.then(response => response.json()) |
|
.then(json => dispatch({ |
|
type: 'add', |
|
payload: json |
|
})) |
|
} |
|
] |
|
|
|
|
|
|
|
const createStore = (reducer, state, middleware) => { |
|
if((typeof state === 'function') && (typeof middleware === 'undefined')){ |
|
middleware = state; |
|
state = undefined; |
|
} |
|
|
|
if(typeof middleware !== 'undefined') return middleware(createStore)(reducer, state); |
|
|
|
const eventList = []; |
|
const getState = () => eventList.reduce(reducer, state); |
|
const dispatch = (action) => { |
|
eventList.push(action); |
|
listeners.forEach(x => x()) |
|
} |
|
|
|
const listeners = []; |
|
const subscribe = (f) => listeners.push(f); |
|
return { |
|
getState, |
|
dispatch, |
|
subscribe |
|
} |
|
} |
|
|
|
const composeReducers = (...reducers) => |
|
(previousState, action) => |
|
R.reduce((newState, reducer) => reducer(newState, action), previousState, reducers); |
|
|
|
|
|
|
|
const applyMiddleware = (...middlewares) => (createStore) => (reducer, state, middleware) => { |
|
const store = createStore(reducer, state, middleware); |
|
const dispatch = store.dispatch; |
|
const middlewareAPI = { |
|
getState: store.getState, |
|
dispatch: (action) => dispatch(action) |
|
} |
|
|
|
const chain = middlewares.map(m => m(middlewareAPI)); |
|
const composedChain = R.compose(...chain); |
|
|
|
return { |
|
...store, |
|
dispatch: composedChain(dispatch) |
|
} |
|
} |
|
|
|
const thunkMiddleware = ({dispatch, getState}) => (next) => (action) => |
|
(typeof action === 'function') ? action(dispatch, getState) |
|
: next(action); |
|
|
|
const reducers = composeReducers(r1); |
|
|
|
const store = createStore(reducers, [], applyMiddleware(thunkMiddleware)); |
|
|
|
|
|
store.subscribe(() => console.log('\n\n\n\n',JSON.stringify(store.getState(), null, 4))); |
|
|
|
actions.map(store.dispatch); |
|
|
|
store.dispatch((dispatch) => fetch('https://jsonplaceholder.typicode.com/users/1') |
|
.then(response => response.json()) |
|
.then(json => dispatch({ |
|
type: 'add', |
|
payload: json |
|
}))) |
|
|
|
window.setTimeout(() => console.log(JSON.stringify(store.getState(), null, 4)), 1000) |