React(react18)中组件通信05——react-redux

2023-09-21 22:23:12

1. 前言

1.1 React中组件通信的其他方式

1.2 介绍React-Redux

1.2.1 简单介绍React-Redux

  • React-Redux是Redux 官方提供的 React 绑定库。 具有高效且灵活的特性。
    • react-redux 是一个专为 React 应用开发而设计的基于 Redux 的库,提供了一些特定于 React 的功能和组件。
    • 它提供了一系列的 API 和组件,方便在 React 组件中使用 Redux 进行状态管理。
  • React-Redux 在概念上非常简单。它订阅 Redux 存储,检查组件所需的数据是否已更改,并重新渲染组件
  • react-redux 提供了一些特定于 React 的功能,如 connect 函数和 Provider 组件,用于连接 Redux 的 store,并将状态传递给 React 组件。
    • React Redux 提供的 <Provider /> 组件,这使得 Redux store 能够在应用的其他地方使用(即:store只需在入口文件传递一次,其他需要store的容器组件中都可以获取)。

1.2.2 官网

1.3 安装react-redux

  • 安装命令如下:
    # If you use npm:
    npm install react-redux
    
    # Or if you use Yarn:
    yarn add react-redux
    

2. 简单改写redux的例子

2.1 提供store

  • 第一步我们需要使得 store 对于我们的应用是可见的。为了做到这个,我们使用 React Redux 提供的 API <Provider /> 去包裹我们的应用。:
    • 首先先给改写后的目录结构
      在这里插入图片描述
    • 然后再看app.js 和 index.js
      在这里插入图片描述

2.2 连接 Components + UI组件修改

2.2.1 连接 Components

  • 先看官网怎么讲解的
    在这里插入图片描述

  • 先简单写写实现效果,后续再优化,如下:
    在这里插入图片描述

    import CountNumRedux from "../components/CountNumRedux";
    import { connect } from "react-redux";
    import store from '../redux/store'
    
    //这里ownProps如果用不到的话,可以不传,可以只传state
    const mapStateToProps = (state, ownProps) => ({
          // ...依据 state 和 自定义 ownProps 生成 computed data
          /**
           * 即状态统一在容器组件中管理
           * UI组件使用的话直接通过props取就行了,这种方式也相当于通过props传递
           * 如果监听state的变化,一有变化就调用,并把state通过props传递给UI组件
           */
          count:state
        //   name:'麦兜'
      });
    
      const mapDispatchToProps = ()=>({
        // ... 通常是一个充满 action creators 的 object
           addNumber:(number)=>{
               store.dispatch(
                   { type: 'INCREMENT', number:number }
               )
           },
           reduceNumber:(number)=>{
               store.dispatch(
                   { type: 'DECREMENT', number:number }
               )
           }
     });
    
      
    //   // 1. `connect` 返回一个接收要包装的组件的新函数:
    //   const connectToStore = connect(mapStateToProps, mapDispatchToProps);
    
    //   // 2. 并且该函数返回连接的,包装的组件:
    //   const ConnectedComponent = connectToStore(Component);
      
      // 通常我们会将两者一步完成,像这样:
    const CountNumContainer = connect(mapStateToProps, mapDispatchToProps)(CountNumRedux);
    
    export default CountNumContainer;
    

2.2.2 修改UI组件

  • 如下:
    在这里插入图片描述

    import {  createRef } from "react";
    // import store from '../redux/store'
    // import countAction from '../redux/countAction'
    
    function CountNumRedux(props){
        console.log(props);
    
        // const [count,setCount] = useState(0);
        const numberRef = createRef();
    
        function add(){
            let number = numberRef.current.value;
            // console.log(typeof number);  //string
            // store.dispatch(countAction.incrementNum(parseInt(number)));
            props.addNumber(parseInt(number));
        }
    
        function subtract(){
            let number = parseInt(numberRef.current.value);
            props.reduceNumber(number);
        }
    
        // useEffect(()=>{
        //     store.subscribe(()=>{
        //         console.log('订阅更新,打印2-----',store.getState());
        //         setCount(store.getState());
        //     });
        // });
    
        return(
            <div>
                {/* 当前数字是:{count}    &nbsp;&nbsp;&nbsp;&nbsp;
                当前数字是:{store.getState()}   */}
    
                当前数值是:{props.count}
                <br />
                浮动数字:<input type="number" ref={numberRef}/>
    
                <br /><br />
                <button onClick={add}>点我 加数</button> <br /><br />
                <button onClick={subtract}>点我 减数</button>
            </div>
        )
    }
    export default CountNumRedux;
    

2.2.3 看效果

  • 如下:
    在这里插入图片描述

2.3 连接 Components——优化(优化容器组件)

  • 主要优化 mapDispatchToProps,用封装好的action,如下:

    import CountNumRedux from "../components/CountNumRedux";
    import { connect } from "react-redux";
    // import store from '../redux/store'
    import {incrementNum,decrementNum} from "../redux/countAction";
    
    
    const mapStateToProps = (state) => ({
          count:state
      });
    
    
    //   const mapDispatchToProps = ()=>({
    //        addNumber:(number)=>{
    //            store.dispatch(
    //                { type: 'INCREMENT', number:number }
    //            )
    //        },
    //        reduceNumber:(number)=>{
    //            store.dispatch(
    //                { type: 'DECREMENT', number:number }
    //            )
    //        }
    //  });
    
    /**
     * 1. dispatch:react-redux 会将dispatch传入,所以不用引入store来调了
     * 2. 引入已经封装好的action:countAction
     */
     const mapDispatchToProps = (dispatch)=>({
        addNumber:(number)=>{
            dispatch( incrementNum(number) )
        },
        reduceNumber:(number)=>{
            dispatch( decrementNum(number) )
        }
    });
    
    const CountNumContainer = connect(mapStateToProps, mapDispatchToProps)(CountNumRedux);
    
    export default CountNumContainer;
    

2.4 优化容器组件(可怕的精简)

  • mapDispatchToProps: 此参数可以是一个 function,或者一个 object。
    • 上面都是用function写的,接下来换成object之后,代码真的太少了!
    • 不妨再看一下官方强调的:
      在这里插入图片描述
  • 精简代码如下:
    /**
     * 优化2
     */
    const mapDispatchToProps = {
        //通常是一个充满 action creators 的 object
        addNumber: incrementNum,   //addNumber:是通过props传递给UI组件的方法, incrementNum:是封装好的action函数
        reduceNumber: decrementNum
    }
    
    对比一下:
    在这里插入图片描述

2.5 附代码

  • 关于redux文件下的代码就不贴了,因为没改动,需要的直接上篇文章就行,其他如下:
    • CountNumContainer.jsx
      import CountNumRedux from "../components/CountNumRedux";
      import { connect } from "react-redux";
      import {incrementNum,decrementNum} from "../redux/countAction";
      
      const mapStateToProps = (state) => ({
            count:state
        });
      
      const mapDispatchToProps = {
          //通常是一个充满 action creators 的 object
          addNumber: incrementNum,   //addNumber:是通过props传递给UI组件的方法, incrementNum:是封装好的action函数
          reduceNumber: decrementNum
      }
      
      const CountNumContainer = connect(mapStateToProps, mapDispatchToProps)(CountNumRedux);
      
      export default CountNumContainer;
      
    • CountNumRedux.jsx
      import {  createRef } from "react";
      
      function CountNumRedux(props){
          console.log(props);
          
          const numberRef = createRef();
      
          function add(){
              let number = numberRef.current.value;
              props.addNumber(parseInt(number));
          }
      
          function subtract(){
              let number = parseInt(numberRef.current.value);
              props.reduceNumber(number);
          }
      
          return(
              <div>
                  {/* 当前数字是:{count}    &nbsp;&nbsp;&nbsp;&nbsp;
                  当前数字是:{store.getState()}   */}
      
                  当前数值是:{props.count}
                  <br />
                  浮动数字:<input type="number" ref={numberRef}/>
      
                  <br /><br />
                  <button onClick={add}>点我 加数</button> <br /><br />
                  <button onClick={subtract}>点我 减数</button>
              </div>
          )
      }
      export default CountNumRedux;
      
    • App.js
      import CountNumContainer from './container/CountNumContainer.jsx'
      
      function App() {
        return (
          <div>
            {/* <CountNumRedux/> */}
            <CountNumContainer/>
          </div>
        );
      }
      
      export default App;
      
    • 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';
      
      
      const root = ReactDOM.createRoot(document.getElementById('root'));
      root.render(
          <Provider store={store}>
              <App />
          </Provider>
      );
      
      export default root;
      

3. 附项目

更多推荐

企业架构LNMP学习笔记60

Tomcat企业常见使用方法;1)简单代码测试:将两个jsp文件上传到ROOT目录下。查看下这个jsp代码:test.jsp<html><head><title>HelloWorld</title><%@pagelanguage="java"contentType="text/html;charset=UTF-8"pa

半年总结 -要有松弛感的慢生活

匆匆的半年就这样又过去了,菊次郎的夏天也过完了,国庆又要到了,正在发愁国庆节七天要干什么,然后前几天了解省考要提前到1月份,得,这下不就有事情要做了么😏进入正题吧~工作自从去年年末换到新公司,到现在渐渐的适应了这里的工作和同事,尤其是前几个月,感觉像是突破了自己,做了几个自认为比较有挑战性的工作,有些技术,任务之前听

智能配电系统:保障电力运行安全、可控与高效

智能配电系统是一种先进的电力分配技术,它通过智能化、数字化和网络化等方式,有效地保障了电力运行的安全、可控和高效。力安科技智能配电系统是在配电室(含高压柜、变压器、低压柜)、箱式变电站、配电箱及动力柜(箱)、智能终端箱实现智能化、网络化、数字化的基础上,通过移动互联网接入电易云,建设用户智能配电系统服务云管理平台。借助

Mozilla 紧急修补 Firefox 和 Thunderbird 中的 WebP 严重零日漏洞

Mozilla周二发布了安全更新,修复了Firefox和Thunderbird中的一个关键零日漏洞。该漏洞被标记为CVE-2023-4863,是WebP图像格式中的堆缓冲区溢出漏洞,在处理特制图像时可能导致任意代码执行。Mozilla在一份公告中说,打开恶意WebP图像可能导致内容进程中的堆缓冲区溢出,这个漏洞在其他产

AR导览软件定制开发方案

随着智能手机的普及和人们对文化、旅游等方面的需求不断增加,导览软件市场前景广阔。本文将围绕导览软件定制开发方案展开,包括以下部分:一、行业现状及市场需求导览软件市场发展迅速,各类导览软件层出不穷。通过对市场竞争对手的分析,我们发现目前导览软件主要分为两类:1)传统导览软件:以导游解说和景区导览为主,功能相对简单;2)智

魔众题库系统 v8.8.0 公式编辑升级,注册站内信和邮件,手机Banner支持视频背景

魔众题库系统基于PHP开发,可以用于题库管理和试卷生成软件,拥有极简界面和强大的功能,用户遍及全国各行各业。魔众题库系统发布v8.8.0版本,新功能和Bug修复累计23项,公式编辑升级,注册站内信和邮件,手机Banner支持视频背景。2023年09月19日魔众题库系统发布v8.8.0版本,增加了以下23个特性:·[新功

坚鹏:中国邮政储蓄银行金融科技前沿技术发展与应用场景第4期

中国邮政储蓄银行金融科技前沿技术发展与应用场景第4期培训圆满结束中国邮政储蓄银行拥有优良的资产质量和显著的成长潜力,是中国领先的大型零售银行。2016年9月在香港联交所挂牌上市,2019年12月在上交所挂牌上市。中国邮政储蓄银行拥有近4万个营业网点,服务个人客户超6.5亿户。2022年,在《银行家》(TheBanker

外汇天眼:英国FCA引入新规定,强化金融广告审核标准!

英国金融行为监管局(FCA)为帮助人们做出明智的储蓄、投资和借贷决策,将引入新的筛选检查措施,针对那些批准金融广告的公司。批准非受监管公司的金融营销的公司必须证明他们具备批准广告所需的技能和专业知识。那些签署广告批准的人必须了解产品,以确保广告的宣传准确,并合理平衡风险和回报。以前,受FCA授权的任何公司都可以代表不受

Java 21 发布,新功能助力开发更高效

Java21是JavaSE平台的最新长期支持(LTS)版本,于2023年9月19日发布。它包括了一系列新功能和改进,可以让开发人员编写更高效、更可靠、更安全的Java应用程序。新功能亮点Java21的新功能包括:虚拟线程:虚拟线程是一种新的并发模型,可以使开发人员编写更高效的并发代码,而无需担心线程调度和同步的复杂性。

IP转地理位置:探讨技术与应用

IP地址是互联网上设备的唯一标识符,而将IP地址转换为地理位置信息是网络管理、安全监控和市场定位等领域中的一项重要任务。本文将深入探讨IP转地理位置的技术原理和各种应用场景。IP地址与地理位置IP地址(InternetProtocolAddress)是一组数字,用于唯一标识互联网上的设备。它们分为IPv4(32位地址)

深入了解Java的核心库

掌握Java的核心库是成为一名优秀的Java开发者的关键。Java提供了丰富的核心库和API,包括集合框架、输入输出、多线程、异常处理等等。熟悉并掌握这些库的使用,可以提高编程效率和代码质量。在本文中,我们将深入讨论Java的核心库,并提供一些代码示例来帮助读者更好地理解和掌握这些库。1.集合框架:Java的集合框架提

热文推荐