redux应用与原理

186 阅读2分钟

一. 为什么要用redux?

  • 来一张图看看😂

二. redux是什么?

  • 再来一张图看看😂

三. redux三大原则

  • 唯一数据源
    • 整个应用的state都被存储到一个状态树里面,并且这个状态树,只存在于唯一的store中。
  • 保持只读状态
    • state是只读的,唯一改变state的方法就是触发action,action是一个用于描述以发生时间的普通对象。
  • 数据改变只能通过纯函数来执行
    • 使用纯函数来执行修改,为了描述action如何改变state的,你需要编写reducers。

四. redux的使用

  • 先来了解几个核心概念
    • store:存储数据的仓库
    • reducer:初始化state并定义state修改规则
    • dispatch:提交action(reducer定义好的),修改store数据的一个方法
    • getState:获取状态值
    • subscribe:订阅state状态更新
  • 上代码
    • 创建store,src/store.js
    import {createStore} from 'redux'
    
    const counterReducer = (state = 0, action) => {
      switch (action.type) {
        case 'add':
          return state + 1
        case 'minus':
          return state - 1
        default: 
          return state
      }
    }
    const store = createStore(counterReducer)
    
    export default store
    
    • 创建page,src/view/counter.js
    import React, { Component } from "react";
    import store from "../store";
    
    export default class counter extends Component {
      componentDidMount() {
        // 订阅状态变更,强制刷新。
        // 如果不这么做,数据更新之后,页面不会刷新,这点和vuex不一样,因为vuex有响应式,但是它没有。
        store.subscribe(() => this.forceUpdate());
      }
      render() {
        return (
          <div>
            <!-- 获取state的值 -->
          	<p>{store.getState()}</p>
          	<div>
          	    <button onClick={() => store.dispatch({ type: "add" })}>+</button>
          	    <button onClick={() => store.dispatch({ type: "minus" })}>-</button>
          	 </div>
          </div>
        );
      }
    }
    
    • 订阅状态变更,index.js
    import store from './store'
    
    const render = () => {
      ReactDom.render(
        <App/>,
        document.querySelector('#root')
      )
    }
    
    render()
    
    store.subscribe(render)
    

五. 说了应用,咱们再聊聊实现

  • 咱们这次核心要实现的是四个模块:state,getState,dispatch,subscribe
  • 代码如下
    export function createStore (reducer, enhancer) {
      if (enhancer) {
        // 除了创建store之外,再做一些其他事情
        return enhancer(createStore)(reducer)
      }
    	
      // 保存状态
      let currentState = undefined;
      let currentListeners = []; // 回调函数的数组
    
      function getState () {
        return currentState
      }
    
      // 订阅模式
      function subscribe (listener) {
        currentListeners.push(listener)
      }
    
      // 更新状态
      function dispatch (action) {
        // 修改
        currentState = reducer(currentState, action)
        // 变更通知
        currentListeners.forEach(listener => listener())
        return action
      }
    
      return { getState, subscribe, dispatch}
    
    }
    

六. 总结

  • 单纯的使用redux,每次数据更新,都需要强制刷新有些麻烦,react为我们提供的react-redux可以帮我们解决这个问题,下次可以重点聊聊。