20分钟搞懂Redux概念

688 阅读2分钟

一、课程目标

  • Redux 基础概念(Action、Reducer、State)
  • 异步Action的处理
  • Redux中间件原理

二、知识要点

官网 www.redux.org.cn/

1. 搭建环境

# 创建项目
npx create-react-app redux
#or
create-react-app redux

1. Redux入门

JavaScript 需要管理比任何时候都要多的 state (状态)

1.1 统一状态管理需要完成什么功能

  • 更新状态
  • 获取状态
  • 状态变更通知 - (最好是订阅发布模式)

1.2 演示

// store.js

import { createStore } from 'redux'

const action = {
    clear: { type: 'clear' },
    add: { type: 'add', payload: 1 },
}

const reducer = (state = { num: 100 }, action) => {
    switch (action.type) {
        case 'clear':
            return { num: 0 }
        case 'add':
            return { num: state.num + action.payload }
        default:
            return state
    }
}

const store = createStore(
    reducer
)

// 建立响应订阅
store.subscribe(() => console.log('update', store.getState()))
store.dispatch(action['clear'])
store.dispatch(action['add'])


//App.js
import React from 'react'
import store from './store'
class App extends React.Component{
    render(){
        return <div>
            
        </div>
    }
}
export default App

1.3 总结三大原则

  • 单一数据源

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

  • State 是只读的

唯一改变 state 的方法就是触发 action,action 是一个用于描述已发生事件的普通对象。

  • 使用纯函数来执行修改

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

** **

3. 异步Action

const action = {
        // ...
    asyncAdd: dispatch => {
        setTimeout(() => {
            dispatch({ type: 'add', payload: 2 })
        }, 1000)
    }
}
// action['asyncAdd'](store.dispatch)
store.dispatch(action['asyncAdd'])

4. Redux中间件

4.1 logger 与 thunk

import { createStore, applyMiddleware } from 'redux'

const logger = ({ dispatch, getState }) => next => action => {
    console.log('start: ' ,action)
    next(action)
    console.log('end: ' ,action)
    return 
}
const thunk = ({ dispatch, getState }) => next => action => {
    if (typeof action === 'function') {
        return action(dispatch)
    }
    next(action)
    return 
}

const store = createStore(
    reducer,
    applyMiddleware(...[
        logger,
        thunk
    ])
)

// 可以利用
// import logger from 'redux-logger'
// import thunk from 'redux-thunk'
// const store = createStore(
//     reducer,
//     applyMiddleware(...[
//         logger,
//         thunk
//     ])
// )

4.3 第三方中间件

// 可以利用
import logger from 'redux-logger'
import thunk from 'redux-thunk'
const store = createStore(
    reducer,
    applyMiddleware(...[
        logger,
        thunk
    ])
)

5 与React结合

import React from 'react'
import store from './store'

import ReactDom from 'react-dom'
const render = () => {

  ReactDom.render(
    <App />,
    document.querySelector('#root')
  )
}
store.subscribe(render)

class App extends React.Component {

  render() {
    return <div><div>
      <p>{store.getState().num}</p>
      <div>
        <button onClick={() => store.dispatch({ type: "clear" })}>clear</button>
        <button onClick={() => store.dispatch({ type: "add", payload: 1 })}>add</button>
        <button onClick={() => {
          store.dispatch(dispatch => {
            setTimeout(() => {
              dispatch({ type: "add", payload: 2 })
            }, 1000)
          })
        }
        }>asyncAdd</button>

      </div>
    </div>
    </div>
  }
}
export default App