【React】入门Day03 —— Redux 与 React Router 核心概念及应用实例详解

1. Redux 介绍

// 创建一个简单的Redux store
const { createStore } = Redux;// reducer函数
function counterReducer(state = { count: 0 }, action) {switch (action.type) {case 'INCREMENT':return { count: state.count + 1 };case 'DECREMENT':return { count: state.count - 1 };default:return state;}
}// 创建store实例
const store = createStore(counterReducer);// 订阅数据变化
store.subscribe(() => {console.log(store.getState());
});// 触发数据变化
store.dispatch({ type: 'INCREMENT' });
  • 概念

    • 是 React 常用的集中状态管理工具,可独立于框架运行,类似于 Vue 中的 Pinia(Vuex)。
    • 通过集中管理方式管理应用状态。
  • 使用原因

    • 独立于组件,无视层级关系,简化通信。
    • 单向数据流清晰,易于定位 bug。
    • 调试工具配套良好,方便调试。

2. Redux 快速体验

<button id="decrement">-</button>
<span id="count">0</span>
<button id="increment">+</button>
<script src="https://unpkg.com/redux@latest/dist/redux.min.js"></script>
<script>// 定义reducer函数 function counterReducer (state = { count: 0 }, action) {switch (action.type) {case 'INCREMENT':return { count: state.count + 1 }case 'DECREMENT':return { count: state.count - 1 }default:return state}}const store = Redux.createStore(counterReducer);store.subscribe(() => {document.getElementById('count').innerText = store.getState().count;});const inBtn = document.getElementById('increment');inBtn.addEventListener('click', () => {store.dispatch({ type: 'INCREMENT' });});const dBtn = document.getElementById('decrement');dBtn.addEventListener('click', () => {store.dispatch({ type: 'DECREMENT' });});
</script>
  • 计数器实现

    • 定义 reducer 函数,根据 action 返回新状态。
    • 使用 createStore 传入 reducer 生成 store 实例。
    • 用 store 的 subscribe 方法订阅数据变化。
    • 通过 store 的 dispatch 方法提交 action 触发变化。
    • 利用 store 的 getState 方法获取最新状态更新视图。
  • 数据流架构

    // 定义state
    const initialState = { count: 0 };// 定义action
    const incrementAction = { type: 'INCREMENT' };// 定义reducer
    function counterReducer(state = initialState, action) {switch (action.type) {case 'INCREMENT':return { count: state.count + 1 };default:return state;}
    }
    • 包含 state(存放数据对象)、action(描述数据修改对象)、reducer(根据 action 更新 state 的函数)三个核心概念。

3. Redux 与 React

# 创建React项目
npx create-react-app react-redux # 安装配套工具
npm i @reduxjs/toolkit  react-redux # 启动项目
npm run start 
  • 环境准备

    • 安装 Redux Toolkit(RTK)和 react-redux。
    • 使用 CRA 创建 React 项目,安装配套工具并启动。
    • 设计 store 目录结构,包括单独的 store 目录和内部的 modules 目录,入口文件组合子模块并导出 store。
  • 实现 counter

    // counterStore.js
    import { createSlice } from '@reduxjs/toolkit';const counterStore = createSlice({name: 'counter',initialState: { count: 1 },reducers: {increment(state) {state.count++;},decrement(state) {state.count--;}}
    });const { increment, decrement } = counterStore.actions;
    const counterReducer = counterStore.reducer;
    export { increment, decrement };
    export default counterReducer;// store.js
    import { configureStore } from '@reduxjs/toolkit';
    import counterReducer from './modules/counterStore';
    export default configureStore({reducer: {counter: counterReducer}
    });// App.jsx
    import React from 'react';
    import ReactDOM from 'react-dom/client';
    import App from './App';
    import store from './store';
    import { Provider } from 'react-redux';
    ReactDOM.createRoot(document.getElementById('root')).render(<Provider store={store}><App /></Provider>
    );// 在组件中使用store数据
    import { useSelector } from 'react-redux';
    const count = useSelector(state => state.counter.count);// 在组件中修改store数据
    import { useDispatch } from 'react-redux';
    const dispatch = useDispatch();
    dispatch(increment());
    • 使用 React Toolkit 创建 counterStore,定义模块名称、初始数据和修改数据的同步方法。
    • 为 React 注入 store,使用 Provider 组件传递 store 实例。
    • React 组件中用 useSelector 获取 store 数据,用 useDispatch 修改 store 数据。
  • 提交 action 传参

    // reducer函数
    function counterReducer(state = { count: 0 }, action) {switch (action.type) {case 'INCREMENT_WITH_PARAM':return { count: action.payload.targetCount };default:return state;}
    }// 触发action并传递参数
    const targetCount = 10;
    store.dispatch({ type: 'INCREMENT_WITH_PARAM', payload: { targetCount } });
    • 在 reducers 同步修改方法中添加 action 对象参数,调用 actionCreater 时传递参数到 action 对象的 payload 属性。
  • 异步 action 处理

    // channelStore.js
    import { createSlice } from '@reduxjs/toolkit';
    import axios from 'axios';const channelStore = createSlice({name: 'channel',initialState: { channelList: [] },reducers: {setChannelList(state, action) {state.channelList = action.payload;}}
    });const { setChannelList } = channelStore.actions;
    const url = 'http://geek.itheima.net/v1_0/channels';
    const fetchChannelList = () => {return async (dispatch) => {const res = await axios.get(url);dispatch(setChannelList(res.data.data.channels));}
    };
    export { fetchChannelList };
    const channelReducer = channelStore.reducer;
    export default channelReducer;// App.jsx
    import { useEffect } from 'react';
    import { useSelector, useDispatch } from 'react-redux';
    import { fetchChannelList } from './store/channelStore';function App() {const { channelList } = useSelector(state => state.channel);useEffect(() => {dispatch(fetchChannelList());}, [dispatch]);return (<div className="App"><ul>{channelList.map(task => <li key={task.id}>{task.name}</li>)}</ul></div>);
    }
    export default App;
    • 创建 store 配置同步方法,单独封装函数,在新函数中封装异步请求获取数据并调用同步 actionCreater 生成 action 对象提交。

4. Redux 调试

  • 官方提供调试工具,支持实时 state 信息展示和 action 提交信息查看。

5. 路由快速上手

// 假设已有一个简单的React组件结构
import React from 'react';
import ReactDOM from 'react-dom/client';// 定义两个简单组件
const LoginComponent = () => <div>登录页面内容</div>;
const ArticleComponent = () => <div>文章页面内容</div>;// 这里模拟路由配置(实际使用React Router的配置方式会更复杂)
const routes = [{ path: '/login', component: LoginComponent },{ path: '/article', component: ArticleComponent }
];// 根据当前路径渲染相应组件(这里是简化的逻辑,实际需要根据React Router的机制来实现)
const App = () => {const currentPath = window.location.pathname;const ComponentToRender = routes.find(route => route.path === currentPath)?.component || null;return <>{ComponentToRender}</>;
};ReactDOM.createRoot(document.getElementById('root')).render(<App />);
  • 前端路由概念

    • 一个路径对应一个组件,访问路径时对应组件在页面渲染。
  • 开发环境创建

    # 使用CRA创建项目
    npm create-react-app react-router-pro# 安装最新的ReactRouter包
    npm i react-router-dom# 启动项目
    npm run start
    • 使用 CRA 创建项目,安装 React Router 包,启动项目。
  • 快速开始

    import React from 'react';
    import ReactDOM from 'react-dom/client';
    import { createBrowserRouter, RouterProvider } from 'react-router-dom';const router = createBrowserRouter([{path: '/login',element: <div>登录</div>},{path: '/article',element: <div>文章</div>},
    ]);ReactDOM.createRoot(document.getElementById('root')).render(<RouterProvider router={router} />
    );
    • 使用createBrowserRouter创建路由,配置路径和对应组件,通过RouterProvider渲染路由。

6. 抽象路由模块

// 假设这是一个简单的路由模块文件
import { createBrowserRouter, RouterProvider } from 'react-router-dom';// 定义各个路由组件
const HomeComponent = () => <div>首页</div>;
const AboutComponent = () => <div>关于我们</div>;
const ContactComponent = () => <div>联系我们</div>;// 创建路由配置
const router = createBrowserRouter([{path: '/',element: HomeComponent},{path: '/about',element: AboutComponent},{path: '/contact',element: ContactComponent}
]);// 导出路由配置供其他文件使用
export default router;
  • (文档中未详细说明相关内容,可能需要进一步查看实际模块相关代码)

7. 路由导航

  • 概念

    • 路由系统中多个路由间需进行跳转及参数传递通信。
  • 声明式导航

    import React from 'react';
    import { Link } from 'react-router-dom';const NavMenu = () => (<nav><Link to="/home">首页</Link><Link to="/about">关于</Link><Link to="/contact">联系</Link></nav>
    );
    • 通过<Link/>组件,指定to属性为路由路径实现跳转,传参可字符串拼接。
  • 编程式导航

    import React from 'react';
    import { useNavigate } from 'react-router-dom';const LoginButton = () => {const navigate = useNavigate();const handleLogin = () => {// 假设这里是登录逻辑,登录成功后进行跳转navigate('/dashboard');};return <button onClick={handleLogin}>登录</button>;
    };
    • 使用useNavigate钩子获取导航方法,调用navigate方法传入路径实现跳转,更灵活。

8. 导航传参

import React from 'react';
import { useNavigate } from 'react-router-dom';const ProductDetailButton = () => {const navigate = useNavigate();const productId = 123; // 假设这是一个产品IDconst handleNavigate = () => {navigate(`/product/${productId}`);};return <button onClick={handleNavigate}>查看产品详情</button>;
};
  • (文档中未详细说明相关内容,可能需要进一步查看实际传参相关代码)

9. 嵌套路由配置

  • 概念

    • 一级路由中内嵌其他路由为嵌套路由,内嵌的为二级路由。
      import React from 'react';
      import { createBrowserRouter, RouterProvider } from 'react-router-dom';// 定义子路由组件
      const SubPage1 = () => <div>子页面1</div>;
      const SubPage2 = () => <div>子页面2</div>;// 一级路由组件
      const MainPage = () => <div>主页面</div>;// 创建嵌套路由配置
      const router = createBrowserRouter([{path: '/main',element: MainPage,children: [{path: 'sub1',element: SubPage1},{path: 'sub2',element: SubPage2}]}
      ]);ReactDOM.createRoot(document.getElementById('root')).render(<RouterProvider router={router} />
      );
  • 配置步骤

    • 使用children属性配置嵌套关系,用<Outlet/>组件配置二级路由渲染位置。
      import React from 'react';
      import { createBrowserRouter, RouterProvider, Outlet } from 'react-router-dom';// 定义子路由组件
      const SubPage1 = () => <div>子页面1</div>;
      const SubPage2 = () => <div>子页面2</div>;// 一级路由组件
      const MainPage = () => <div>主页面,这里可以放置一些通用的内容,子页面会在Outlet处渲染</div>;// 创建嵌套路由配置
      const router = createBrowserRouter([{path: '/main',element: MainPage,children: [{path: 'sub1',element: SubPage1},{path: 'sub2',element: SubPage2}]}
      ]);ReactDOM.createRoot(document.getElementById('root')).render(<RouterProvider router={router}><MainPage><Outlet /></MainPage></RouterProvider>
      );
  • 默认二级路由

    • 访问一级路由时,二级路由去掉路径,设置index属性为true可默认渲染。
      import React from 'react';
      import { createBrowserRouter, RouterProvider, Outlet } from 'react-router-dom';// 定义子路由组件
      const SubPage = () => <div>默认子页面</div>;// 一级路由组件
      const MainPage = () => <div>主页面,这里可以放置一些通用的内容,子页面会在Outlet处渲染</div>;// 创建嵌套路由配置
      const router = createBrowserRouter([{path: '/main',element: MainPage,children: [{path: '',index: true,element: SubPage}]}
      ]);ReactDOM.createRoot(document.getElementById('root')).render(<RouterProvider router={router}><MainPage><Outlet /></MainPage></RouterProvider>
      );
  • 404 路由配置

    • 准备NotFound组件,在路由表末尾用*作为路径配置路由。
      import React from 'react';
      import { createBrowserRouter, RouterProvider } from 'react-router-dom';
      import NotFoundComponent from './NotFoundComponent';// 其他路由配置
      const router = createBrowserRouter([//...其他路由{path: '*',element: NotFoundComponent}
      ]);ReactDOM.createRoot(document.getElementById('root')).render(<RouterProvider router={router} />
      );
  • 路由模式

    • 常用history模式和hash模式。
      • history模式:url表现为url/login,基于history对象和pushState事件,需后端支持。
        import React from 'react';
        import { createBrowserRouter, RouterProvider } from 'react-router-dom';// 假设后端已正确配置处理history模式的路由请求const router = createBrowserRouter([{path: '/login',element: <div>登录页面内容</div>},{path: '/article',element: <div>文章页面内容</div>}
        ]);ReactDOM.createRoot(document.getElementById('root')).render(<RouterProvider router={router} />
        );
      • hash模式:url表现为url/#/login,监听hashChange事件,无需后端支持。
        import React from 'react';
        import { createHashRouter, RouterProvider } from 'react-router-dom';const router = createHashRouter([{path: '/login',element: <div>登录页面内容</div>},{path: '/article',element: <div>文章页面内容</div>}
        ]);ReactDOM.createRoot(document.getElementById('root')).render(<RouterProvider router={router} />
        );

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/442977.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

智能医疗:Spring Boot医院管理系统开发

2相关技术 2.1 MYSQL数据库 MySQL是一个真正的多用户、多线程SQL数据库服务器。 是基于SQL的客户/服务器模式的关系数据库管理系统&#xff0c;它的有点有有功能强大、使用简单、管理方便、安全可靠性高、运行速度快、多线程、跨平台性、完全网络化、稳定性等&#xff0c;非常适…

行为设计模式 -观察者模式- JAVA

观察者模式 一.简介二. 案例2.1 抽象主题&#xff08;Subject&#xff09;2.2 具体主题&#xff08;Concrete Subject&#xff09;2.3 抽象观察者&#xff08;Observer&#xff09;2.4 具体观察者&#xff08;Concrete Observer&#xff09;2.5 测试 三. 结论3.1 优缺点3.2 使用…

Vortex GPGPU的github流程跑通与功能模块波形探索(二)

文章目录 前言一、环境配置和debugging.md文档1.1 调试 Vortex GPU1.1.1测试 RTL 或模拟器 GPU 驱动的更改1.1.2 SimX 调试1.1.3 RTL 调试1.1.4 FPGA 调试1.1.5 分析 Vortex 跟踪日志 二、跑出波形文件和日志文件总结 前言 昨天另辟蹊径地去探索了子模块的波形仿真&#xff0c…

【简介Sentinel-1】

Sentinel-1是欧洲航天局哥白尼计划&#xff08;GMES&#xff09;中的地球观测卫星&#xff0c;由Sentinel-1A和Sentinel-1B两颗卫星组成。以下是对Sentinel-1的详细介绍&#xff1a; 一、基本信息 卫星名称&#xff1a;Sentinel-1 所属计划&#xff1a;欧洲航天局哥白尼计划…

【含开题报告+文档+PPT+源码】基于SSM框架的民宿酒店预定系统的设计与实现

开题报告 随着人们旅游需求的增加&#xff0c;民宿行业呈现出快速发展的趋势。传统的住宿方式逐渐无法满足人们对个性化、舒适、便捷的需求&#xff0c;而民宿作为一种新型的住宿选择&#xff0c;逐渐受到人们的青睐。民宿的特点是具有独特的风格、便捷的地理位置、相对亲近的…

简单使用DrissionPage网页自动化工具

DrissionPage 是一个基于 python 的网页自动化工具&#xff0c;类似Selenium&#xff0c;可以操控浏览器进行一些自动测试&#xff0c;也可以直接发请求&#xff1b; 官网&#xff1a;DrissionPage官网 &#xff08;那个浏览器黑白图标一眼看去还以为是只哭泣的小猪&#xff0…

云计算Openstack Neutron

OpenStack Neutron是OpenStack云计算平台中的网络服务组件&#xff0c;它为OpenStack提供了强大的网络连接功能。 一、基本概念 Neutron是一个网络服务项目&#xff0c;旨在为OpenStack提供网络连接。它允许用户创建和管理虚拟网络&#xff0c;包括子网、路由、安全组等&…

VMWare安装和基本使用NixOS Linux 24.05版本

文章目录 简介Nix 语言基础知识NixOS 虚拟机创建 VMWare 的 NixOS 虚拟机安装说明Nix 包管理器安装Windows(WSL)上安装Linux 上安装Docker 上安装MacOS 上安装NixOS 的安装下载 ISO 镜像安装 NixOS修改语言网络配置设置位置设置键盘设置账号和密码桌面环境分区完成安装登录系…

MFC多媒体定时器实例(源码下载)

用MFC多媒体定时器做一个每1秒钟加一次的计时器&#xff0c;点开始计时按钮开始计时&#xff0c;点关闭计时按钮关闭计时。 1、在库文件Med_timeDlg.h文件中添加代码 class CMed_timeDlg : public CDialog { // Construction public:CMed_timeDlg(CWnd* pParent NULL); // st…

Microsoft 更新 Copilot AI,未來將能使用語音並看到你瀏覽的網頁

不過受到 Recall 事件的影響&#xff0c;更新的推出將更緩慢謹慎。 Microsoft 也同步對其網頁版及行動版的 Copilot AI 進行大改版。這主要是為網頁版換上了一個較為簡單乾淨的介面&#xff0c;並增加了一些新的功能&#xff0c;像是 Copilot Voice 能讓你與 AI 助手進行對話式…

HTML5实现古典音乐网站源码模板1

文章目录 1.设计来源1.1 网站首页1.2 古典音乐界面1.3 著名人物界面1.4 古典乐器界面1.5 历史起源界面2.效果和源码2.1 动态效果2.2 源代码源码下载万套模板,程序开发,在线开发,在线沟通作者:xcLeigh 文章地址:https://blog.csdn.net/weixin_43151418/article/details/142…

【韩顺平Java笔记】第8章:面向对象编程(中级部分)【285-296】

文章目录 285. 为什么需要继承286. 继承原理图287. 继承快速入门288. 289. 290. 291. 292. 继承使用细节1,2,3,4,5288.1 继承给编程带来的便利288.2 继承的深入讨论/细节问题 293. 继承本质详解294. 继承课堂练习1295. 继承课堂练习2296. 继承课堂练习3 285. 为什么需要继承 28…

【微服务】服务注册与发现、分布式配置管理 - Consul(day5)

概述 作用 Consul的两大作用就是服务发现和注册与分布式配置管理。 服务发现在介绍Eureka组件的时候已经进行过详细概述&#xff0c;大概就是将硬编码到服务中的IP地址和端口号进行解耦&#xff0c;从而实现动态扩缩容、容错处理、服务管理等功能&#xff0c;通过服务注册和…

台球助教预约小程序源码开发:技术解析与示例代码

随着数字化时代的到来&#xff0c;信息技术与体育运动的融合日益紧密。台球作为一项深受大众喜爱的运动&#xff0c;其教学训练领域也迎来了技术创新的浪潮。本文将探讨台球助教预约小程序的开发过程&#xff0c;从技术选型、功能设计到示例代码展示renxb001&#xff0c;全面解…

yub‘s Algorithmic Adventures_Day7

环形链表 link&#xff1a;https://leetcode.cn/problems/linked-list-cycle-ii/description/ 思路分析 我只能说双指针yyds【刻板hh】 我们分两种情况来分析 起码在第二圈才会相遇 fast比slow多走环的整数倍 fast 走的步数是 slow 步数的 2 倍&#xff0c;即 f2s&#xff…

计算机网络:计算机网络体系结构 —— 专用术语总结

文章目录 专用术语实体协议服务服务访问点 SAP 服务原语 SP 协议数据单元 PDU服务数据单元 SDU 专用术语 实体 实体是指任何可以发送或接收信息的硬件或软件进程 对等实体是指通信双方处于相同层次中的实体&#xff0c;如通信双方应用层的浏览器进程和 Web 服务器进程。 协…

Kubernetes中部署ELK Stack日志收集平台

1 、ELK概念 ELK是Elasticsearch、Logstash、Kibana三大开源框架首字母大写简称。市面上也被成为Elastic Stack。其中: Elasticsearch是一个基于Lucene、分布式、通过Restful方式进行交互的近实时搜索平台框架。像类似百度、谷歌这种大数据全文搜索引擎的场景都可以使用Elas…

单目3d重建DUSt3R 笔记

目录 DUSt3R 三维重建 报错RecursionError: maximum recursion depth exceeded in comparison 报错 numpy.core.multiarray failed to import 报错Numpy is not available 解决 升级版mast3r 速度变慢 修改了参数设置脚本&#xff1a; 测试效果 操作技巧 DUSt3R 三维重…

重学SpringBoot3-集成Redis(九)之共享Session

更多SpringBoot3内容请关注我的专栏&#xff1a;《SpringBoot3》 期待您的点赞&#x1f44d;收藏⭐评论✍ 重学SpringBoot3-集成Redis&#xff08;九&#xff09;之共享Session 1. 为什么需要 Session 共享2. Spring Session 和 Redis 的集成2.1. 引入依赖2.2. 配置 Redis 连接…

基于单片机的智能浇花系统

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于51单片机&#xff0c;采样DHT11温湿度传感器检测温湿度&#xff0c;通过LCD1602显示 4*4按键矩阵可以设置温度湿度阈值&#xff0c;温度大于阈值则开启水泵&#xff0c;湿度大于阈值则开启风扇…