Redux 简单如耙

我已经访问过redux存储库 ,但是从某个地方我想到了实现它的想法。 我想与社区分享我的震惊甚至令人失望的发现。

TL; DR:核心redux逻辑适合7行JS代码。

简而言之,关于redux(github上头的免费翻译):
Redux是JavaScript应用程序的状态管理库。

它有助于编写性能稳定/可预测,可在不同环境(客户端/服务器/本机代码)中运行且易于测试的应用程序。
克隆了redux存储库 ,在编辑器中打开了source文件夹(忽略docsexamples等),并用剪刀抓住 Delete键:

  • 从代码中删除了所有注释
    每个库方法都使用JSDoc详细记录。
  • 删除了错误验证和日志记录
    在每种方法中,输入参数都是通过控制台非常详细的注释输出来严格控制的
  • 删除了bindActionCreatorssubscribereplaceReducer可观察的方法

    ...因为他可以。 好吧,或者因为我懒得为他们写例子。 但是如果没有极端情况,它们甚至比前面的情况更有趣。

现在让我们看一下还剩下什么



在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() 
// [{ id: 1, text: '  redux ', completed: false }]

store.dispatch({
  type: 'TOGGLE_TODO',
  id: 1
})

store.getState() 
// [{ id: 1, text: '  redux ', completed: true }]

, show must go on.
, .

combineReducers


, , reducer , .

:

//     todosReducer   

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
, , , , , (, , )

, createStore

function 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 . ?

Source: https://habr.com/ru/post/zh-CN439104/


All Articles