• <react求和案例>react-redux基本使用与优化——Provider/mapDispatch


    上篇文章初步了解和学习了react-redux的原理和组件拆分
    今天探索一下react-redux基本使用以及对求和案例的代码优化
    感兴趣的小伙伴一起来看看吧!🤞

    在这里插入图片描述

    ⭐react-redux基本使用

    依旧对求和案例进行分析:
    在这里插入图片描述

    根据react-redux模型图,实现了Count的容器组件与Count的UI组件的联系,接下来要实现容器组件给UI组件传递 redux中所保存的状态以及操作状态的方法,要借助props

    但是不能像原先父子组件传参利用标签的方式传递,比如:

    <A>
      <B a='1' b='2'/>
    <A/>
    
    • 1
    • 2
    • 3

    那么如何在容器组件(父组件)向UI组件传递参数呢?

    由于父子组件关系是靠connect形成的,所以connect函数在第一次调用的时候要传入两个参数,参数必须是函数类型的,这样react-redux库就帮你调用这两个函数,一个函数返回值作为状态,另一个函数返回值作为操作状态的方法。

    // react-redux API默认要给connect两个函数作为参数,两个函数会收到来至redux传来的值和方法。
    export default connect(mapStateToProps, mapDispatchToProps)(CountUI)
    
    • 1
    • 2

    mapStateToProps()函数的返回值作为 状态 传递给了UI组件,函数返回的是一个对象,mapStateToProps函数返回的对象中的key就作为传递给UI组件props的key,value就作为传递给UI组件props的value。

    由于要获取redux里的状态,就要store.getState(),就要在容器组件里引入store,但是之前已经在上层App.jsx里向容器组件传了store,就不需要自己引入了,这里也不需要我们自己去获取状态,react-redux帮我们调mapStateToProps()函数时,已经帮我们把状态传过去了,只需要mapStateToProps(state)接收一下即可。

    function mapStateToProps(state) {
      return { count: state }
    }
    
    • 1
    • 2
    • 3

    这样UI组件就可以通过 this.props 接收到 状态

    <h1>当前求和为:{this.props.count}</h1>
    
    • 1

    mapDispatchToProps()函数的返回值作为 操作状态的方法 传递给了UI组件,函数返回的是一个对象,mapDispatchToProps函数返回的对象中的key就作为传递给UI组件props的key,value就作为传递给UI组件props的value。

    由于要实现加这个运算,就要在jia这个回调函数里通知redux执行加法,就要调用store.dispatch(action)这个方法,这里又要引入store操作状态,但是这里也不需要store调用dispatch方法,react-redux帮我们把dispatch()方法传过去了,直接用即可。

    // 引入action
    import {
      createIncrementAction,
      createDecrementAction,
      createIncrementAsyncAction
    } from '../../redux/count_action'
    function mapDispatchToProps(dispatch) {
      return {
        jia: (number) => {
          // 通知redux执行加法
          dispatch(createIncrementAction(number))
        },
        jian: (number) => {
          // 通知redux执行减法
          dispatch(createDecrementAction(number))
        },
        jiaAsync: (number, time) => {
          // 通知redux执行异步加法
          dispatch(createIncrementAsyncAction(number, time))
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    这样UI组件就可以通过 this.props 接收到 操作状态的方法

    // 加法
    increment = () => {
      // 获取用户输入
      const { value } = this.selectNumber
      this.props.jia(value * 1)
    }
    
    // 减法
    decrement = () => {
      // 获取用户输入
      const { value } = this.selectNumber
      this.props.jian(value * 1)
    }
    
    // 奇数再加
    incrementIfOdd = () => {
      // 获取用户输入
      const { value } = this.selectNumber
      if (this.props.count % 2 !== 0) {
        this.props.jia(value * 1)
      }
    }
    
    // 异步加
    incrementAsync = () => {
      // 获取用户输入
      const { value } = this.selectNumber
      this.props.jiaAsync(value * 1, 500)
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    src=> components=> Count => index.jsx:

    import React, { Component } from 'react'
    
    export default class Count extends Component {
    
      // 加法
      increment = () => {
        // 获取用户输入
        const { value } = this.selectNumber
        this.props.jia(value * 1)
      }
    
      // 减法
      decrement = () => {
        // 获取用户输入
        const { value } = this.selectNumber
        this.props.jian(value * 1)
      }
    
      // 奇数再加
      incrementIfOdd = () => {
        // 获取用户输入
        const { value } = this.selectNumber
        if (this.props.count % 2 !== 0) {
          this.props.jia(value * 1)
        }
      }
    
      // 异步加
      incrementAsync = () => {
        // 获取用户输入
        const { value } = this.selectNumber
        this.props.jiaAsync(value * 1, 500)
      }
    
      render() {
        // console.log('UI组件接收到的props是:', this.props)
        return (
          <div>
            <h1>当前求和为:{this.props.count}</h1>
            <select ref={c => this.selectNumber = c}>
              <option value="1">1</option>
              <option value="2">2</option>
              <option value="3">3</option>
            </select>&nbsp;
            <button onClick={this.increment}>+</button>&nbsp;
            <button onClick={this.decrement}>-</button>&nbsp;
            <button onClick={this.incrementIfOdd}>当前求和为奇数再加</button>&nbsp;
            <button onClick={this.incrementAsync}>异步加</button>
          </div>
        )
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52

    src=> containers=> Count => index.jsx:

    // 引入Count的UI组件
    import CountUI from '../../components/Count'
    // 引入action
    import {
      createIncrementAction,
      createDecrementAction,
      createIncrementAsyncAction
    } from '../../redux/count_action'
    
    // 引入connect用于连接UI组件与redux
    import { connect } from 'react-redux'
    
    function mapStateToProps(state) {
      return { count: state }
    }
    
    function mapDispatchToProps(dispatch) {
      return {
        jia: (number) => {
          // 通知redux执行加法
          dispatch(createIncrementAction(number))
        },
        jian: (number) => {
          dispatch(createDecrementAction(number))
        },
        jiaAsync: (number, time) => {
          dispatch(createIncrementAsyncAction(number, time))
        }
      }
    }
    
    export default connect(mapStateToProps, mapDispatchToProps)(CountUI)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    ⛳求和案例_react-redux基本使用总结

    1️⃣明确两个概念:

    • UI组件:不能使用任何redux的api,只负责页面的呈现、交互等。
    • 容器组件:负责和redux通信,将结果交给UI组件

    2️⃣如何创建一个容器组件———依靠react-redux的connect函数

    connect(mapStateToProps,mapDispatchToProps)(UI组件)

    • mapStateToProps:映射状态,返回值是一个对象
    • mapDispatchToProps:映射操作状态的方法,返回值是一个对象

    3️⃣ 备注:容器组件中的store是靠props传进去的,而不是在容器组件中直接引入

    ⭐优化1:简写mapDispatch

    优化前:

    // 映射状态
    function mapStateToProps(state) {
      return { count: state }
    }
    
    • 1
    • 2
    • 3
    • 4

    优化后:

    // 映射状态
    const mapStateToProps = state => ({ count: state })
    
    • 1
    • 2

    优化前:

    // 映射操作状态的方法
    function mapDispatchToProps(dispatch) {
      return {
        jia: (number) => {
          // 通知redux执行加法
          dispatch(createIncrementAction(number))
        },
        jian: (number) => {
          dispatch(createDecrementAction(number))
        },
        jiaAsync: (number, time) => {
          dispatch(createIncrementAsyncAction(number, time))
        }
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    优化后:

    // 映射操作状态的方法
    const mapDispatchToProps = dispatch => (
      {
        jia: number => dispatch(createIncrementAction(number)),
        jian: number => dispatch(createDecrementAction(number)),
        jiaAsync: (number, time) => 
        dispatch(createIncrementAsyncAction(number, time))
      }
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    再优化后:

    // 引入Count的UI组件
    import CountUI from '../../components/Count'
    // 引入action
    import {
      createIncrementAction,
      createDecrementAction,
      createIncrementAsyncAction
    } from '../../redux/count_action'
    
    // 引入connect用于连接UI组件与redux
    import { connect } from 'react-redux'
    
    //使用connect()()创建并暴露一个Count的容器组件
    // react-redux API默认要给connect两个函数作为参数,两个函数会收到来至redux传来的值和方法。
    export default connect(
      state => ({ count: state }),
      dispatch => (
        {
          jia: number => dispatch(createIncrementAction(number)),
        	jian: number => dispatch(createDecrementAction(number)),
        	jiaAsync: (number, time) => 
        	dispatch(createIncrementAsyncAction(number, time))
        }
      )
    )(CountUI)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    mapDispatchToProps的简写:

    export default connect(
      state => ({ count: state }),
    
      // mapDispatchToProps的一般写法
      // dispatch => (
      //   {
      //     jia: number => dispatch(createIncrementAction(number)),
      //     jian: number => dispatch(createDecrementAction(number)),
      //     jiaAsync: (number, time) =>
      //       dispatch(createIncrementAsyncAction(number, time))
      //   }
      // )
    
      // mapDispatchToProps的简写
      {
        jia: createIncrementAction,
        jian: createDecrementAction,
        jiaAsync: createIncrementAsyncAction
      }
    )(CountUI)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    分析mapDispatchToProps的简写

    {
      jia: createIncrementAction,
      jian: createDecrementAction,
      jiaAsync: createIncrementAsyncAction
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    Count的UI组件里调用了jia函数,传递了用户选择的参数,然后在容器组件里调用了createIncrementAction方法,返回值是一个action对象,react-redux帮我们自动dispatch了。

    mapDispatchToProps可以写成一个普通的函数,也可以是一个对象

    react-redux还有一个优势:不用自己监测redux的状态是否发生了变化,内部的所有逻辑全部交给容器组件来完成,避免污染整个app组件。

    ⭐优化2:Provider组件的使用

    App.jsx:

    import React, { Component } from 'react'
    import Count from './containers/Count'
    import store from './redux/store'
    
    export default class App extends Component {
      render() {
        return (
          <div>
            {/* 渲染容器组件,给容器组件传递store */}
            <Count store={store} />
          </div>
        )
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    当项目中有多个容器组件时,每次都要给容器组件传递store,这样不太方便,所以:我们可以在index.js入口文件里引入react-redux里的一个API——Provider

    把所有容器组件都需要的store交给Provider,Provider会自动分析整个项目里所有的容器组件,把store传给每一个需要store的容器组件。

    index.js:

    import React from 'react';
    import ReactDOM from 'react-dom/client'
    import App from './App'
    import store from './redux/store'
    import { Provider } from 'react-redux'
    
    // 创建虚拟DOM
    const root = ReactDOM.createRoot(document.getElementById('root'))
    // 渲染虚拟DOM到页面
    root.render(
      <React.StrictMode>
        {/* 检查App组件以及子组件里的一些代码是否有不合理的地方 */}
        <Provider store={store}>
          <App />
        </Provider>
      </React.StrictMode>
    )
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    ⭐优化3:整合UI组件与容器组件

    前面两个优化,我们分别从代码层面和API层面进行了优化。在这里,我们将在文件层面对UI组件和容器组件进行优化。

    由于我们学习了react-redux库,要求为组件分别写成UI组件和容器组件。那么如果在整个应用中,有20个组件需要和redux打交道,那么我们就需要写40个组件…可想而知,这样写是不行的,我们可以作出一些优化:

    可以将UI组件和容器组件整合在同一个文件夹里。

    在这里插入图片描述

    /src/containers/Count/index.jsx:

    import React, { Component } from 'react'
    // 引入action
    import {
      createIncrementAction,
      createDecrementAction,
      createIncrementAsyncAction
    } from '../../redux/count_action'
    // 引入connect用于连接UI组件与redux
    import { connect } from 'react-redux'
    
    // 定义UI组件
    class Count extends Component {
      // 加法
      increment = () => {
        const { value } = this.selectNumber
        this.props.jia(value * 1)
      }
    
      // 减法
      decrement = () => {
        const { value } = this.selectNumber
        this.props.jian(value * 1)
      }
    
      // 奇数再加
      incrementIfOdd = () => {
        const { value } = this.selectNumber
        if (this.props.count % 2 !== 0) {
          this.props.jia(value * 1)
        }
      }
    
      // 异步加
      incrementAsync = () => {
        const { value } = this.selectNumber
        this.props.jiaAsync(value * 1, 500)
      }
    
      render() {
        return (
          <div>
            <h1>当前求和为:{this.props.count}</h1>
            <select ref={c => this.selectNumber = c}>
              <option value="1">1</option>
              <option value="2">2</option>
              <option value="3">3</option>
            </select>&nbsp;
            <button onClick={this.increment}>+</button>&nbsp;
            <button onClick={this.decrement}>-</button>&nbsp;
            <button onClick={this.incrementIfOdd}>当前求和为奇数再加</button>&nbsp;
            <button onClick={this.incrementAsync}>异步加</button>
          </div>
        )
      }
    }
    
    //使用connect()()创建并暴露一个Count的容器组件
    export default connect(
      state => ({ count: state }),
      // mapDispatchToProps的简写
      {
        jia: createIncrementAction,
        jian: createDecrementAction,
        jiaAsync: createIncrementAsyncAction
      }
    )(Count)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66

    ⛳求和案例_react-redux优化总结

    1️⃣ 容器组件和UI组件整合成一个文件

    2️⃣ 无需自己给容器组件传递store,给 < < <App/>包裹一个 < < <Provider store={store}>即可。

    3️⃣ 使用了react-redux后也不用再自己监测redux中状态的改变了,容器组件可以自动完成这个工作。

    4️⃣ mapDispatchToProps也可以简单的写成一个对象。

    5️⃣ 一个组件要和redux“打交道”要经过哪几步?

    • 定义好UI组件—不暴露

    • 引入connect生成一个容器组件,并暴露,写法如下:

      connect(
        state => ({key:value}), //映射状态
        {key:xxxxAction}  //映射操作状态的方法
      )(UI组件)
      
      • 1
      • 2
      • 3
      • 4
    • 在UI组件中通过this.props.xxxxxx读取和操作状态

    今天的分享就到这里啦✨ \textcolor{red}{今天的分享就到这里啦✨} 今天的分享就到这里啦

    原创不易,还希望各位大佬支持一下 \textcolor{blue}{原创不易,还希望各位大佬支持一下} 原创不易,还希望各位大佬支持一下

    🤞 点赞,你的认可是我创作的动力! \textcolor{green}{点赞,你的认可是我创作的动力!} 点赞,你的认可是我创作的动力!

    ⭐️ 收藏,你的青睐是我努力的方向! \textcolor{green}{收藏,你的青睐是我努力的方向!} 收藏,你的青睐是我努力的方向!

    ✏️ 评论,你的意见是我进步的财富! \textcolor{green}{评论,你的意见是我进步的财富!} 评论,你的意见是我进步的财富!

  • 相关阅读:
    Arrays.asList() 和 List.of() 的列表之争
    java 数字计算不能使用float
    有关iframe锚点,锚点出现上下偏移,锚点出现页面显示问题.iframe的srcdoc问题
    从6月25日考试之后,看新考纲如何复习PMP
    今日AI:GPT-4.5意外曝光可能6月发布、UP主借AI识别情绪播放量186万、全球首个AI程序员诞生
    基于VScode 使用plantUML 插件设计状态机
    Canal实现Mysql和ES数据同步
    用AI模型实现两种图像是否相同的验证
    基于图搜索的规划算法之可视图法
    2.4 - 网络协议 - TCP协议工作原理,报文格式,抓包实战,UDP报文,UDP检错原理
  • 原文地址:https://blog.csdn.net/xuxuii/article/details/126156866