• Redux学习与使用



    Redux并不是必需的,只有在项目存在多交互、多数据源的场景才应该考虑使用,其设计思想可总结为:Web 应用是一个状态机,视图与状态是一一对应的,所有的状态,保存在一个对象里面。

    一、基本概念及常用API

    1、Store即是保存数据的地方,通过createStore函数生成Store

    import { createStore } from 'redux';
    const store = createStore(fn);
    
    • 1
    • 2

    2、State就是状态,是数据的集合,可以通过store.getState()拿到

    const state = store.getState();
    
    • 1

    3、Action 是一个对象,是View发出的通知,通知State该发生变化了,其中type属性是必须的

    const action = {
      type: 'ADD_TODO',
      payload: 'Learn Redux'
    };
    
    • 1
    • 2
    • 3
    • 4

    4、Action Creator就是可以生成Action的函数

    const ADD_TODO = '添加 TODO';
    
    function addTodo(text) {
      return {
        type: ADD_TODO,
        text
      }
    }
    
    const action = addTodo('Learn Redux');
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    5、store.dispatch()是 View 发出 Action 的唯一方法

    store.dispatch(addTodo('Learn Redux'));
    
    • 1

    6、Reducer 是一个纯函数,它接受 Action 和当前 State 作为参数,返回一个新的 State

    const reducer = function (state, action) {
      // ...
      return new_state;
    };
    
    • 1
    • 2
    • 3
    • 4

    7、store.subscribe方法可设置监听函数,一旦 State 发生变化,就自动执行这个函数,调用该方法返回的函数,即可解除监听

    import { createStore } from 'redux';
    const store = createStore(reducer);
    
    store.subscribe(listener);
    
    let unsubscribe = store.subscribe(() =>
      console.log(store.getState())
    );
    
    unsubscribe();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    二、Store的实现

    生成Store的createStore方法可以接受两个参数

    let store = createStore(reducer, window.STATE_FROM_SERVER)
    
    • 1

    Store 提供了三个方法: subscribe, dispatch, getState,其简单实现如下

    const createStore = (reducer) => {
      let state; // 状态
      let listeners = []; // 监听
    
      const getState = () => state;
    
      const dispatch = (action) => {
        state = reducer(state, action);
        listeners.forEach(listener => listener());
      };
    
      const subscribe = (listener) => {
        listeners.push(listener);
        return () => {
          listeners = listeners.filter(l => l !== listener);
        }
      };
    
      dispatch({});
    
      return { getState, dispatch, subscribe };
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    三、Reducer的拆分和组合

    可以将一个庞大的Reducer根据不同的属性处理,拆分不同的子函数,最终通过combineReducers方法合并

    import { combineReducers } from 'redux';
    
    const chatReducer = combineReducers({
      chatLog,
      statusMessage,
      userName
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    可以把所有子 Reducer 放在一个文件里面,然后统一引入

    import { combineReducers } from 'redux'
    import * as reducers from './reducers'
    
    const reducer = combineReducers(reducers)
    
    • 1
    • 2
    • 3
    • 4

    四、Redux工作流程

    首先,用户发出 Action

    store.dispatch(action);
    
    • 1

    然后,Store 自动调用 Reducer,并且传入两个参数:当前 State 和收到的 Action,Reducer 会返回新的 State

    let nextState = todoApp(previousState, action);
    
    • 1

    State 一旦有变化,Store 就会调用监听函数。

    // 设置监听函数
    store.subscribe(listener);
    
    • 1
    • 2

    listener可以通过store.getState()得到当前状态。如果使用的是 React,这时可以触发重新渲染 View。

    function listerner() {
      let newState = store.getState();
      component.setState(newState);   
    }
    
    • 1
    • 2
    • 3
    • 4

    五、Redux中间件以及异步操作

    异步操作就是在 Action 发出以后,过一段时间再执行 Reducer,这需求用到中间件。中间件就是一个函数,可以添加功能,通过applyMiddleware方法进行使用

    import { applyMiddleware, createStore } from 'redux';
    import createLogger from 'redux-logger';
    const logger = createLogger();
    
    const store = createStore(
      reducer,
      applyMiddleware(logger)
    );
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    applyMiddlewares是 Redux 的原生方法,作用是将所有中间件组成一个数组,依次执行。

    异步操作的思路可以理解为:

    • 操作开始时,送出一个 Action,触发 State 更新为"正在操作"状态,View 重新渲染
    • 操作结束后,再送出一个 Action,触发 State 更新为"操作结束"状态,View 再一次重新渲染

    六、React-Redux的使用

    React-Redux 将所有组件分成两大类:UI 组件(presentational component)和容器组件(container component)。

    UI 组件有以下几个特征:

    • 只负责 UI 的呈现,不带有任何业务逻辑
    • 没有状态(即不使用this.state这个变量)
    • 所有数据都由参数(this.props)提供
    • 不使用任何 Redux 的 API
    const Title =
      value => 

    {value}

    ;
    • 1
    • 2

    容器组件的特征:

    • 负责管理数据和业务逻辑,不负责 UI 的呈现
    • 带有内部状态
    • 使用 Redux 的 API

    React-Redux 提供connect方法,用于从 UI 组件生成容器组件

    import { connect } from 'react-redux'
    
    const VisibleTodoList = connect(
      mapStateToProps,
      mapDispatchToProps
    )(TodoList)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    TodoList是 UI 组件,VisibleTodoList就是由 React-Redux 通过connect方法自动生成的容器组件,mapStateToProps负责输入逻辑,即将state映射到 UI 组件的参数(props),mapDispatchToProps负责输出逻辑,即将用户对 UI 组件的操作映射成 Action

    connect方法生成容器组件以后,需要让容器组件拿到state对象,才能生成 UI 组件的参数,React-Redux 提供Provider组件,可以让容器组件拿到state

    import { Provider } from 'react-redux'
    import { createStore } from 'redux'
    import todoApp from './reducers'
    import App from './components/App'
    
    let store = createStore(todoApp);
    
    render(
      
        
      ,
      document.getElementById('root')
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    上面代码中,Provider在根组件外面包了一层,这样一来,App的所有子组件就默认都可以拿到state

    Refs:

    Redux 入门教程(一):基本用法

    Redux 入门教程(二):中间件与异步操作

    Redux 入门教程(三):React-Redux 的用法

  • 相关阅读:
    聊聊HttpClient的KeepAlive
    多线程处理文件集合,先拆分,在执行
    python的进制转换与数据类型转换
    Java认识异常(超级详细)
    【Python】pyinstaller打包百科全书
    PostgreSQL heap堆表 存储引擎实现原理
    PAT 1037 Magic Coupon(贪心)
    AutoCAD2019开发配置
    C# 13(.Net 9) 中的新特性 - 扩展类型
    常见DDoS攻击
  • 原文地址:https://blog.csdn.net/weixin_44942126/article/details/126645694