美文网首页
Redux基础入门

Redux基础入门

作者: CC前端手记 | 来源:发表于2020-06-12 10:48 被阅读0次

    随着js应用的日益复杂化,状态管理越来越成为前端开发的必要条件。一些库依然没有提供处理state中数据问题的合适方法,恰好redux可以帮我们搞定这个难题。

    核心概念

    要更新state中的数据,就要发起一个action来描述发生了什么。然后用一个reducer函数,接收 state 和 action并返回新state,来实现state的更新。当然,实际开发中往往需要编写很多小函数分别管理state的一部分,再开发一个reducer调用这两个reducer,管理整个state。

    state可能是这样的:

    {
      todos: [{
        text: 'Eat food',
        completed: true
      }, {
        text: 'Exercise',
        completed: false
      }],
      visibilityFilter: 'SHOW_COMPLETED'
    }
    

    action可能是这样的:

    { type: 'ADD', text: 'Go to swimming pool' }
    { type: 'TOGGLE', index: 1 }
    { type: 'SET_FILTER', filter: 'SHOW_ALL' }
    

    reducer可能是这样:

    function Filter(state = 'SHOW_ALL', action) {
      if (action.type === 'SET_FILTER') {
        return action.filter
      } else {
        return state
      }
    }
    function todos(state = [], action) {
      switch (action.type) {
        case 'ADD':
          return state.concat([{ text: action.text, completed: false }])
        case 'TOGGLE':
          return state.map((todo, index) =>
            action.index === index
              ? { text: todo.text, completed: !todo.completed }
              : todo
          )
        default:
          return state
      }
    }
    function todoApp(state = {}, action) {
      return {
        todos: todos(state.todos, action),
        visibilityFilter: visibilityFilter(state.visibilityFilter, action)
      }
    }
    

    三大原则:

    1、数据源是单一的:

    整个应用的state被储存在一棵object tree中,并且这个object tree只存在于唯一一个store中。

    2、state是只读的:

    唯一改变 state 的方法就是触发action。

    3、使用纯函数执行修改:

    为了描述 action 如何改变 state tree,你需要编写reducers。

    Action:

    把数据传到store,是store数据的唯一来源。一般用store.dispatch()将action传到store。

    const ADD_TODO = 'ADD_TODO'
    {
      type: ADD_TODO,  // type字段表示将要执行的动作
      text: 'Build my first Redux app'
    }
    

    如果项目规模较大,可以单独存放action:

    import { ADD_TODO, REMOVE_TODO } from '../actionTypes'
    

    例子:

    /* action 类型 */
    export const ADD_TODO = 'ADD_TODO'
    export const TOGGLE_TODO = 'TOGGLE_TODO'
    export const SET_VISIBILITY_FILTER = 'SET_VISIBILITY_FILTER'
    /* 其它常量 */
    export const VisibilityFilters = {
      SHOW_ALL: 'SHOW_ALL',
      SHOW_COMPLETED: 'SHOW_COMPLETED',
      SHOW_ACTIVE: 'SHOW_ACTIVE'
    }
    
    /* action 创建函数 */
    export function addTodo(text) {
      return { type: ADD_TODO, text }
    }
    export function toggleTodo(index) {
      return { type: TOGGLE_TODO, index }
    }
    export function setVisibilityFilter(filter) {
      return { type: SET_VISIBILITY_FILTER, filter }
    }
    

    Reducer:

    1、接受旧的state和action,返回新state。
    2、一定要保持纯净,单纯执行计算,不要修改入参,不要执行跳转或api请求,不要3、调用非纯函数(Date.now()或Math.random()等。)
    3、首次执行时state为undefined,此时可以设置返回初始state。

    function todos(state = [], action) {
      switch (action.type) {
        case ADD_TODO:
          return [
            ...state,
            {
              text: action.text,
              completed: false
            }
          ]
        case TOGGLE_TODO:
          return state.map((todo, index) => {
            if (index === action.index) {
              return Object.assign({}, todo, {
                completed: !todo.completed
              })
            }
            return todo
          })
        default:
          return state
      }
    }
    
    function todoApp(state = initialState, action) {
      switch (action.type) {
        case SET_VISIBILITY_FILTER:
          return Object.assign({}, state, {
            visibilityFilter: action.filter
          })
        case ADD_TODO:
          return Object.assign({}, state, {
            todos: todos(state.todos, action)
          })
        case TOGGLE_TODO:
          return Object.assign({}, state, {
            todos: todos(state.todos, action)
          })
        default:
          return state
      }
    }
    

    源码:

    import { combineReducers } from 'redux'
    import {
        ADD,
        TOGGLE,
        SET_FILTER,
        Filters
    } from './actions'
    const { SHOW_ALL } = Filters
    function Filter(state=SHOW_ALL,action){
        switch(action.type){
              case SET_FITER:
                  return action.filter
              default:
                  return state
        }
    }
    function todos(state=[], action){
        switch(action.type){
            case ADD:
                return [
                    ...state,
                    {
                        text: action.text,
                        completed: false
                    }
              ]
          case TOGGLE:
              return state.map((todo, index) =>{
                  if(index===action.index){
                      return Object.assign((),todo, {
                          completed: !todo.completed
                      })
                  }
                  return todo
              })
          default:
              return state
        }
    }
    const todoApp = combineReducers({
        Filter,
        todos
    })
    export default todoApp
    

    Store:

    只有一个单一的store,把action和reducer联系到一起。
    职责:维持state,提供getState()获取state,提供dispatch(action)更新state,
    通过subscribe(listener)注册监听器,通过subscribe(listener)返回的函数注销监听器。

    我们把上面的combineReducer导入进来,并传递createStore:
    import { createStore } from 'redux'
    import todoApp from './reducers'
    let store = createStore(todoApp)
    

    先看下redux暴露出来的几个方法:### 1、bindActionCreators()、

    2、combineReducers()、

    3、createStore(reducers函数, 初始值initialStore, 中间件middleware)

    返回的方法主要有:

    (1)获取store——store.getState()
    (2)发送action——store.dispatch()
    (3)监听store变化——store.subscribe()
    (4)异步注入reducer——replaceReducer()

    4、applyMiddleware()

    相关文章

      网友评论

          本文标题:Redux基础入门

          本文链接:https://www.haomeiwen.com/subject/ektitktx.html