react-redux 整理

作者: 网恋被骗二块二 | 来源:发表于2022-02-14 20:56 被阅读0次

    安装 redux

    $ npm i redux react-redux
    

    根据案例同步认知 redux 流程


    1. 创建 redux 中的 reducer
      reducer 是进行数据保存和弹出的地方,可以对数据进行修改,根据 action 的对象来执行对应的操作
      state 和 action 参数是必须的
    // 导入自定义判断的变量
    import { addMount, celMount } from "../actions/constants"
    
    
    const initialState = {
        count: 0
    }
    
    /**
     * reducer 纯函数,用于实现状态的同步更新,返回更新后的新状态数据
     * @param {*} state 更新前的状态数据 
     * @param {*} action 描述发生了什么,有 type 与 payload 属性
     * @returns 
     */
    
    //  是数据的保存地方和返回数据的地方
    //  其中的函数是用来操作状态的函数
    //  会根据action对象,来进行对应的操作
    //  state和action为必要参数
    //  state的值会自动更新成返回值
    //  state不能修改(即不能改动state,.splice()这样的方法不能使用)
    //  数组添加:[...state,...]
    //  数组删除:state.filter((item,index)=>{... return true})
    
    const reducer =  (state = initialState, { type, payload }) => {
      switch (type) {
    
      case addMount:
          const copyAdd = {...state}
          copyAdd.count += payload.num
        return copyAdd
    
      case celMount:
          const copyCel = {...state}
          copyCel.count -= payload.num
        return copyCel
    
      default:
        return state
      }
    }
    // 这里是根据对应的 type 完成对数字的增加或减少
    export default reducer
    
    1. 在 reducers 文件夹下创建一个 index.js 文件,作用是使用 combineReducers 方法将多个 reducer 整合成一个 reducer
    // 引入方法
    import { combineReducers } from "redux";
    
    //  引入 reducer
    import counter from "./counter";
    
    // combineReducers 的作用是把很多个 reducer 合并成一个
    export default combineReducers({
        counter
    })
    

    此处关于 reducer 的部分完成,既然需要使用 action,那么还需要完成 action 的部分

    1. 创建 actions 文件夹,下面存放两种文件,一个是需要判断用到的 const 常量,另一种是对应 reducer 用到的 action
    /* 
    判断条件的常量
    因为 switch 用到的 === 判断, 所以为了防止 reducer 或者 action 的数据出错而无法判断
    所以一般都是把这些整合起来
    */
    export const addMount = 'increase'
    export const celMount = 'reduce'
    
    1. 编写需要用到的 action
    import { addMount, celMount } from "./constants";
    
    
    // 生成 action 对象
    // action中存储type类型和数据,会根据type来进行何种操作,数据来进行状态更新
    export const addNumberOfCount = () => ({
        type: addMount,
        payload: {
            num: 5 // 此处每次操作对默认数 +5
        }
    })
    
    export const celNumberOfCount = () => ({
        type: celMount,
        payload:{
            num: 5 // 此处每次操作对默认数 -5
        }
    })
    

    此时需要的 reducer 和 action 都创建和配置好了,那么该创建一个 store 来提供使用了。

    1. 在 store 目录下
    // index.js
    import { createStore } from "redux";
    import reducers from "../reducers";
    
    // 引入 reducer 的方法 这里使用的是 combineReducers 合并的一个集合
    
    export default createStore(reducers)
    
    1. 一切准备工作就绪后,那么就该使用了
      首先在 src 目录下入口文件 index.js 里配置
    import react from "react";
    
    import reactDom from "react-dom";
    
    // 引入 react-redux 的 Provider 即消费组件
    import { Provider } from "react-redux";
    // 引入 store
    import store from "./store";
    
    // import bulma css
    import 'bulma/css/bulma.min.css'
    
    // import component 覆盖 bulma css 样式
    import App from './App'
    
    reactDom.render(
        <Provider store={store}>
            <App />
        </Provider>
        ,
        document.querySelector('#root')
    )
    

    注意这里的 Provider 不是 react.createContext 的 Provider,但具备同样功效,传值

    1. 在需要使用 redux 的地方使用
      如 测试组件(test.jsx)
      因为在入口文件渲染的时候就已经将 App——最大那个组件包裹起来,所有意味着所有组件均可使用 redux 创建的 store
      先用 connect 把所有数据映射到 props 里面才能正常调用
    import React from 'react'
    
    // 引入 需要使用的 action
    import { addNumberOfCount, celNumberOfCount } from '../actions/counter'
    
    // 引入 connect
    import { connect } from 'react-redux'
    
    function Test(props) {
        console.log(props)
      return (
        <>
            <div>
                数字:{ props.count }
            </div>
            <button onClick={props.add}>加</button>
            <button onClick={props.red}>减</button>
        </>
      )
    }
    
    
    // 1. 先映射数据和方法
    // 英文: 映射 state 到 props
    /**
     * 将 store 中 state 的数据映射到组件的属性中
     * mapStateToProps 是一个函数,会传递 store 中的 state 作为参数。
     * 返回一个普通对象,该对象会被合并到组件的 props 中
     * @param {*} state 
     * @returns 
     */
    const mapStateToProps = state => ({
        count: state.counter.count
        // 这里的 state 相当于 vuex 中的最大的仓库
        // counter 就是 reducers 中创建的对应的 reducer
        // 通过 combineReducers 整合到 store 中,相当于 vuex 中注册的 module 模块
    })
    
    /**
     * 将更新状态数据的动作映射到组件的属性中
     * mapDispatchToProps 是一个函数,会传递 dispatch 作为参数。
     * 返回一个对象,返回对象中的各字段应该是函数(方法),返回
     * 对象中的各字段也会被合并到组件的 props 中。
     */
    const mapDispatchToProps = dispatch => ({
        // 这里 通过 dispatch 给 reducer 传递第二个参数,注意 action 需要调用,返回对应的对象
        add: () => dispatch(addNumberOfCount()),
        red: () => dispatch(celNumberOfCount())
    })
    
    //  2. 
    /* 调用 connect() 函数,在 React 组件中,连接 redux 的 store */
    const hoc = connect(mapStateToProps, mapDispatchToProps)
    
    // HOC(HigherOrderComponent)
    // 本质上是一个函数,传递组件作为参数,返回一个新的组件————装饰者设计模式
    export default hoc(Test)
    

    总结:(简书的图片突然又加载失败了= =)


    流程图.png

    借鉴了CSDN博主「神奇大叔」的原创文章,原文链接

    授课老师源码、笔记。

    相关文章

      网友评论

        本文标题:react-redux 整理

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