Redux基础入门

2020-06-12  本文已影响0人  CC前端手记

随着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()

上一篇 下一篇

猜你喜欢

热点阅读