我已经访问过
redux库
存储库 ,但是从某个地方我想到了实现它的想法。 我想与社区分享我的震惊甚至令人失望的发现。
TL; DR:核心redux逻辑适合7行JS代码。
简而言之,关于redux(github上头的免费翻译):
Redux是JavaScript应用程序的状态管理库。
它有助于编写性能稳定/可预测,可在不同环境(客户端/服务器/本机代码)中运行且易于测试的应用程序。
我
克隆了redux存储库 ,在编辑器中打开了source文件夹(忽略
docs ,
examples等),并用
剪刀抓住 Delete键:
- 从代码中删除了所有注释
每个库方法都使用JSDoc详细记录。
- 删除了错误验证和日志记录
在每种方法中,输入参数都是通过控制台非常详细的注释输出来严格控制的
- 删除了bindActionCreators , subscribe , replaceReducer和可观察的方法 。
...因为他可以。 好吧,或者因为我懒得为他们写例子。 但是如果没有极端情况,它们甚至比前面的情况更有趣。
现在让我们看一下还剩下什么
在7行中编写redux
redux的所有基本功能都适合一个小文件,几乎没有人会为此创建一个github存储库:)
function createStore(reducer, initialState) {
let state = initialState
return {
dispatch: action => { state = reducer(state, action) },
getState: () => state,
}
}
. , ,
.
redux. 18 HeadHunter «redux» — , , 7 . — .
7 TodoApp. .
TodoApp redux.
function todosReducer(state, action) {
switch (action.type) {
case 'ADD_TODO':
return [
...state,
{
id: action.id,
text: action.text,
completed: false
}
]
case 'TOGGLE_TODO':
return state.map(todo => {
if (todo.id === action.id) {
return { ...todo, completed: !todo.completed }
}
return todo
})
default:
return state
}
}
const initialTodos = []
const store = createStore(todosReducer, initialTodos)
store.dispatch({
type: 'ADD_TODO',
id: 1,
text: ' redux '
})
store.getState()
store.dispatch({
type: 'TOGGLE_TODO',
id: 1
})
store.getState()
,
show must go on.
, .
combineReducers
, , reducer , .
:
function counterReducer(state, action) {
if (action.type === 'ADD') {
return state + 1
} else {
return state
}
}
const reducer = combineReducers({
todoState: todoReducer,
counterState: counterReducer
})
const initialState = {
todoState: [],
counterState: 0,
}
const store = createStore(reducer, initialState)
store , .
TodoApp .
ES6 (7/8/∞):
const reducer = combineReducers({ todos, counter })
todoReducer todos counterReducer counter. . , , redux, ,
(state.todos) ,
(function todos(){}).
micro-redux, :
function reducer(state, action) {
return {
todoState: todoReducer(state, action),
counterState: counterReducer(state, action),
}
}
. 2 «-»,
(state, action),
, ?, Object.entries
combineReducers (, )
:
function combineReducers(reducersMap) {
return function combinationReducer(state, action) {
const nextState = {}
Object.entries(reducersMap).forEach(([key, reducer]) => {
nextState[key] = reducer(state[key], action)
})
return nextState
}
}
redux 9 .
, , .
applyMiddleware
middleware redux — - , dispatch
-. , , ,… —
-.
middleware createStore, , :
const createStoreWithMiddleware = applyMiddleware(someMiddleware)(createStore)
const store = createStoreWithMiddleware(reducer, initialState)
applyMiddleware, 10 , : createStore «dispatch». dispatch, ( ) , — , (newState = reducer(state, action)).
applyMiddleware
dispatch, ( ) - .
, , middleware redux —
redux-thunk,
store.dispatch({type: 'SOME_ACTION_TYPE', some_useful_data: 1 })
store.dispatch
function someStrangeAction() {
return async function(dispatch, getState) {
if(getState().counterState % 2) {
dispatch({
type: 'ADD',
})
}
await new Promise(resolve => setTimeout(resolve, 1000))
dispatch({
type: 'TOGGLE_TODO',
id: 1
})
}
}
,
dispatch(someStrangeAction())
:
- store.getState().counterState 2, 1
- , todo id=1 completed true false .
, redux-thunk, redux — , ,
:
const thunk = store => dispatch => action => {
if (typeof action === 'function') {
return action(store.dispatch, store.getState)
}
return dispatch(action)
}
,
const thunk = store => dispatch => action
, , , , , (, , )
,
createStorefunction createStore(reducer, initialState) {
let state = initialState
return {
dispatch: action => { state = reducer(state, action) },
getState: () => state,
}
}
(reducer, initialState) { dispatch, getState }.
,
applyMiddleware , , .
createStore :
function applyMiddleware(middleware) {
return function createStoreWithMiddleware(createStore) {
return (reducer, state) => {
const store = createStore(reducer, state)
return {
dispatch: action => middleware(store)(store.dispatch)(action),
getState: store.getState,
}
}
}
}
redux . « , ». , 1 — .
P.S.
«micro-redux» store.subscribe 8 . ?