当前位置: 首页 > news >正文

React中Redux基础和路由介绍

目录

React项目结构介绍 

一、Redux基础使用 

1. 项目初始化

2. 定义 Slice(使用 Redux Toolkit)

3. 配置 Store

4. 应用 Store 到 React

5. 在组件中使用状态

6. 异步操作(Thunk)

核心概念总结

二、React路由介绍 

安装 React Router

1. 基础概念

2. 基本使用示例

在 App.jsx 中设置基础路由

创建简单的页面组件

路由导航

1. 使用<Link>组件进行导航

编程式导航

1使用 useNavigate 实现编程式导航

基本用法

2. navigate 方法的参数

3. 相对路径导航

示例:相对路径跳转

4. 编程式导航与条件判断

示例:根据条件判断进行导航

5. 返回上一页

示例:返回上一页

6. 跳转到首页或其他默认页面

示例:跳转到首页

7. 编程式导航与路由守卫

示例:路由守卫与编程式导航

总结


React项目结构介绍 

my-app/
├── public/                     # 静态资源文件夹
│   ├── index.html              # HTML 模板
│   ├── favicon.ico             # 网站图标
│   └── assets/                 # 静态资源(图片、字体等)
├── src/
│   ├── assets/                 # 存放项目中的静态资源(如图片、字体等)
│   ├── components/             # 可复用的 UI 组件
│   ├── hooks/                  # 自定义 Hook
│   ├── pages/                  # 页面组件(对应不同的路由)
│   ├── routes/                 # 路由配置文件
│   │   └── index.js            # 路由配置文件(定义页面组件的路径映射)
│   ├── services/               # 与 API 交互的服务层(如数据获取、身份验证)
│   ├── store/                  # 状态管理(如 Redux 或 Context API)
│   ├── utils/                  # 工具函数
│   ├── App.js                  # 根组件
│   ├── index.js                # React 入口文件
│   └── styles/                 # 全局样式或主题文件
├── .gitignore                  # Git 忽略文件
├── package.json                # 项目信息和依赖管理
├── README.md                   # 项目说明文件
└── package-lock.json / yarn.lock  # 锁定依赖的版本

一、Redux基础使用 

1. 项目初始化

要先创建一个 React 项目,并且安装 Redux 和 React-Redux。

npx create-react-app redux-demo
cd redux-demo
npm install redux react-redux @reduxjs/toolkit

2. 定义 Slice(使用 Redux Toolkit)

src/features/counter/counterSlice.js文件中定义一个计数器的 slice。

import { createSlice } from '@reduxjs/toolkit';const counterSlice = createSlice({name: 'counter',initialState: {value: 0,},reducers: {increment: (state) => {state.value += 1;},decrement: (state) => {state.value -= 1;},incrementByAmount: (state, action) => {state.value += action.payload;},},
});export const { increment, decrement, incrementByAmount } = counterSlice.actions;
export default counterSlice.reducer;

1. reducers 的作用

在 Redux Toolkit 中,reducers 是 createSlice 函数的核心配置项,用于定义状态修改逻辑。它的主要作用是:

  • 自动生成 Action creators 和 Action types:无需手动编写 action 常量和 action 创建函数。
  • 简化 Redux 逻辑:允许使用 "mutating" 语法(如 state.value += 1),底层通过 Immer 库自动转换为不可变更新。
  • 集中管理状态逻辑:将 action 和 reducer 放在同一个文件中,提高代码可维护性。

counterSlice.js 文件中:

  • incrementdecrementincrementByAmount 都是action creators
  • 每个函数内部的 state 参数是当前状态的副本,修改后会自动生成新的状态。

3. 配置 Store

src/store.js文件中配置 store。

import { configureStore } from '@reduxjs/toolkit';
import counterReducer from './features/counter/counterSlice';export const store = configureStore({reducer: {counter: counterReducer,},
});

4. 应用 Store 到 React

src/index.js文件中使用 Provider 包裹应用。

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import { store } from './store';
import { Provider } from 'react-redux';const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(<Provider store={store}><App /></Provider>
);

5. 在组件中使用状态

src/App.js组件中使用 Redux 状态。

import React from 'react';
import { useSelector, useDispatch } from 'react-redux';
import { increment, decrement, incrementByAmount } from './features/counter/counterSlice';function App() {// 获取状态const count = useSelector((state) => state.counter.value);// 获取dispatch函数const dispatch = useDispatch();return (<div className="App"><h1>计数器: {count}</h1><button onClick={() => dispatch(increment())}>+</button><button onClick={() => dispatch(decrement())}>-</button><button onClick={() => dispatch(incrementByAmount(5))}>+5</button></div>);
}export default App;

6. 异步操作(Thunk)

若需要进行异步操作,可使用 createAsyncThunk

import { createAsyncThunk, createSlice } from '@reduxjs/toolkit';
import axios from 'axios';// 创建异步thunk
export const fetchUserById = createAsyncThunk('users/fetchByIdStatus',async (userId) => {const response = await axios.get(`/api/users/${userId}`);return response.data;}
);const usersSlice = createSlice({name: 'users',initialState: { entities: [], loading: 'idle' },reducers: {},extraReducers: (builder) => {builder.addCase(fetchUserById.pending, (state) => {state.loading = 'pending';}).addCase(fetchUserById.fulfilled, (state, action) => {state.loading = 'idle';state.entities.push(action.payload);});},
});export default usersSlice.reducer;

核心概念总结

  • Store:它是应用状态的容器,一个应用只能有一个 store。
  • Reducer:这是一个纯函数,负责处理 action 并返回新的状态。
  • Action:它是一个描述状态变化的对象,通过 dispatch 来触发。
  • Selector:用于从 store 中选择特定的状态。
  • useSelector:这是一个 React Hook,能让组件从 store 中读取状态。
  • useDispatch:这也是一个 React Hook,可让组件派发 action。

二、React路由介绍 

安装 React Router

首先,你需要安装 react-router-dom,这是 React Router 为 Web 应用提供的包。

npm install react-router-dom

1. 基础概念

  • BrowserRouter: 使用 HTML5 的 history API(pushState、replaceState 和 popstate 事件)来保持 UI 同步。
  • Routes: 路由容器,用于包裹多个 Route 组件。
  • Route: 定义了路径与组件之间的映射关系,当 URL 匹配时显示对应的组件。
  • Link: 用于创建导航链接,不会导致页面刷新。
  • NavLink: 类似于 Link,但可以添加样式以指示当前激活的导航项。
  • Navigate(v6+): 提供编程式导航的能力。
  • useParamsuseSearchParamsuseNavigateuseLocation: 这些 hooks 可以让你访问路由参数、查询参数、执行导航操作以及获取当前的位置信息。

2. 基本使用示例

在 App.jsx 中设置基础路由
// src/App.jsx
import React from 'react';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
import HomePage from './pages/HomePage';
import AboutPage from './pages/AboutPage';
import NotFoundPage from './pages/NotFoundPage';function App() {return (<Router><Routes><Route path="/" element={<HomePage />} /><Route path="/about" element={<AboutPage />} /><Route path="*" element={<NotFoundPage />} /> {/* 404 页面 */}</Routes></Router>);
}export default App;
创建简单的页面组件
// src/pages/HomePage.jsx
import React from 'react';function HomePage() {return <h1>Home Page</h1>;
}export default HomePage;

路由导航

1. 使用 <Link><NavLink> 组件进行导航

<Link> 是 React Router 中用于路由导航的最基础组件,它通过创建一个 <a> 标签,帮助用户在不同的路由之间进行跳转。<Link> 组件会自动拦截浏览器的默认行为,避免页面的完全刷新,保持单页应用(SPA)的特性。
<NavLink><Link> 的一个增强版,它用于自动添加激活样式,帮助你标识当前访问的页面。你可以使用 activeClassName(React Router v5)或者 className(React Router v6)来定义激活链接的样式。

在 React Router v6 中,activeClassName 已被 className 属性替代,className 会根据是否为当前活动路由自动添加特定的样式。

// src/components/Navigation.jsx
import React from 'react';
import { Link, NavLink } from 'react-router-dom';function Navigation() {return (<nav><ul><li><Link to="/">Home</Link></li><li><NavLink to="/about">About</NavLink></li></ul></nav>);
}export default Navigation;

编程式导航

1. 使用 useNavigate 实现编程式导航

在 React Router v6 中,useNavigate 是用来执行编程式导航的钩子。它返回一个函数,可以用来触发路由的跳转。你可以在事件处理函数、生命周期钩子中,或根据某些条件动态地进行路由跳转。

基本用法
import { useNavigate } from 'react-router-dom';function MyComponent() {const navigate = useNavigate();  // 获取导航函数const handleClick = () => {navigate('/about');  // 跳转到 /about 路径};return <button onClick={handleClick}>Go to About</button>;
}

在上面的例子中,当用户点击按钮时,navigate('/about') 会将用户导航到 /about 路由。

2. navigate 方法的参数

navigate 函数可以接收两个参数:

  1. 目标路径 (to): 这是跳转的目标路径,可以是相对路径或绝对路径。

  2. 选项 (options): 这是一个可选对象,允许你配置更多导航行为。常用的选项包括:

    • replace:指定是否替换当前历史记录(类似浏览器的 window.location.replace())。如果设为 true,跳转后当前历史记录将被替换,用户不能按浏览器的“后退”按钮返回。

    • state:你可以通过 state 传递一些状态数据,跳转时携带。

    • relative:指定相对路径跳转。

示例:使用 replacestate

import { useNavigate } from 'react-router-dom';function SubmitForm() {const navigate = useNavigate();const handleSubmit = () => {// 跳转并替换历史记录navigate('/thank-you', { replace: true, state: { fromForm: true } });};return <button onClick={handleSubmit}>Submit</button>;
}

在这个例子中,navigate('/thank-you', { replace: true, state: { fromForm: true } }):

  • 会跳转到 /thank-you 页面。

  • 通过 replace: true 来替换当前历史记录,避免用户按“后退”按钮返回到表单页。

  • 通过 state 参数将一些额外的状态数据传递给目标页面。

3. 相对路径导航

React Router v6 支持相对路径导航,允许你在同一层级的路径上执行跳转。你可以使用相对路径来避免硬编码目标路径。相对路径跳转 是一种基于当前路由上下文的路径跳转方式。它并不依赖于指定一个完整的绝对路径,而是基于当前所在的路由(父路由)计算跳转的目标路径。这种方式通常用于跳转到 当前路由的子路由 或与当前路径相关的目标路径。

路由层级示意图

/
├── /login                        // 登录页
├── /register                     // 注册页
├── /home                         // 首页
└── /dashboard                    // 仪表盘├── /user/:id                 // 用户资料页面│   ├── /user/:id/edit        // 编辑资料页面│   └── /user/:id/settings    // 用户设置页面├── /articles                 // 文章列表页│   ├── /articles/new         // 创建文章页面│   └── /articles/:id/edit    // 编辑文章页面└── /publish                  // 发布文章页面
示例:相对路径跳转
import { useNavigate } from 'react-router-dom';function UserProfile() {const navigate = useNavigate();const goToEditPage = () => {navigate('edit');  // 相对路径跳转,跳转到 /user/:id/edit};return <button onClick={goToEditPage}>Edit Profile</button>;
}

在上面的例子中,navigate('edit') 是相对路径跳转,它会将用户跳转到 /user/:id/edit,其中 :id 是当前页面的动态参数。

4. 编程式导航与条件判断

编程式导航经常与条件判断结合使用,可以根据某些业务逻辑决定是否进行跳转。例如,当用户登录状态发生变化时,或者表单验证通过后,跳转到另一个页面。

示例:根据条件判断进行导航
import { useNavigate } from 'react-router-dom';function LoginPage() {const navigate = useNavigate();const [isAuthenticated, setIsAuthenticated] = useState(false);const handleLogin = (credentials) => {// 假设验证通过if (credentials.username === 'user' && credentials.password === 'password') {setIsAuthenticated(true);navigate('/dashboard');  // 登录成功后跳转到 dashboard 页面} else {alert('Invalid credentials');}};return (<div><button onClick={() => handleLogin({ username: 'user', password: 'password' })}>Login</button></div>);
}

在这个例子中,用户点击登录按钮后,handleLogin 函数会根据条件判断登录是否成功。如果成功,调用 navigate('/dashboard') 来跳转到 /dashboard 页面。

5. 返回上一页

通过 navigate(),你不仅可以跳转到指定的页面,还可以通过传递负数的参数来模拟浏览器的“后退”功能。

示例:返回上一页
import { useNavigate } from 'react-router-dom';function GoBackButton() {const navigate = useNavigate();const goBack = () => {navigate(-1);  // 返回上一页,相当于浏览器的 back 按钮};return <button onClick={goBack}>Go Back</button>;
}

在上面的例子中,navigate(-1) 会使用户返回到历史记录栈中的上一页,相当于浏览器的 "Back" 按钮。

6. 跳转到首页或其他默认页面

navigate() 还可以用来重定向用户到首页或其他默认页面。

示例:跳转到首页
import { useNavigate } from 'react-router-dom';function LogoutButton() {const navigate = useNavigate();const handleLogout = () => {// 清除用户登录信息localStorage.removeItem('authToken');navigate('/');  // 登出后跳转到首页};return <button onClick={handleLogout}>Logout</button>;
}

在这个例子中,用户点击登出按钮后,navigate('/') 会将用户重定向到首页。

7. 编程式导航与路由守卫

在某些情况下,你可能希望在进行导航之前检查某些条件,如用户是否已经登录,或者是否有权限访问某些页面。如果没有满足条件,可以直接跳转到登录页或错误页面。

示例:路由守卫与编程式导航
import { useNavigate } from 'react-router-dom';function ProtectedPage() {const navigate = useNavigate();const isAuthenticated = localStorage.getItem('authToken');if (!isAuthenticated) {navigate('/login');  // 如果用户未认证,则重定向到登录页return null;}return <div>Protected Content</div>;
}

在上面的例子中,ProtectedPage 组件会在渲染之前检查用户是否已认证。如果没有认证,调用 navigate('/login') 重定向用户到登录页面。

总结

编程式导航在 React Router 中非常重要,它允许你在应用中通过代码控制路由跳转,适用于动态场景或根据条件触发跳转。常见的编程式导航方式如下:

  • useNavigate 钩子:通过 navigate() 函数实现导航。

  • 跳转到指定路径navigate('/path')

  • 替换历史记录navigate('/path', { replace: true })

  • 传递状态数据navigate('/path', { state: data })

  • 相对路径跳转navigate('sub-path')

  • 返回上一页navigate(-1)

编程式导航的常见应用场景包括表单提交后跳转、登录验证、路由守卫、动态跳转等。

 

http://www.xdnf.cn/news/1103419.html

相关文章:

  • React 的常用钩子函数在Vue中是如何设计体现出来的。
  • Qt 实现新手引导
  • QT控件 使用QtServer系统服务实现搭建Aria2下载后台服务,并使用Http请求访问Json-RPC接口调用下载退出
  • Grok-4 发布会图文总结
  • docker宿主机修改ip后起不来问题解决
  • 前端面试专栏-算法篇:22.树结构(二叉树、B树、红黑树)
  • 游戏开发日记
  • MyBatis02-mybatis-config.xml配置文件讲解
  • 【深度探究系列(5)】:前端开发打怪升级指南:从踩坑到封神的解决方案手册
  • 基于kafka的分布式日志收集与实时监控平台(原理,框架)
  • 黑马点评系列问题之P55优惠券秒杀 快捷键问题 Ctrl+D显示不出来老师给的界面
  • 液冷智算数据中心崛起,AI算力联动PC Farm与云智算开拓新蓝海(二)
  • 前端Vue.js面试题(2)
  • 【三维重建工具】NeRFStudio、3D GaussianSplatting、Colmap安装与使用指南
  • 飞书CEO谢欣:挑战巨头,打造AI新时代的Office
  • 20250710-2-Kubernetes 集群部署、配置和验证-网络组件存在的意义?_笔记
  • 用Netplan配置网桥bridge笔记250711
  • lodash不支持 Tree Shaking 而 lodash-es可以
  • STM32F407ZGT6天气时钟+实时温湿度显示(附源码)
  • Java结构型模式---组合模式
  • 瀚高数据库提交数据后,是否需要COMMIT(APP)
  • MyBatis 进阶:连接池、动态 SQL 与多表关联查询
  • SpringBoot 使用注解获取配置文件中的值
  • 机器学习-06(Optimization-自动调整学习率)
  • FS820R08A6P2LB——英飞凌高性能IGBT模块,驱动高效能源未来!
  • 线程通信与进程通信的区别笔记
  • Java教程:JavaWeb ---MySQL高级
  • 从语音识别到智能助手:Voice Agent 的技术进化与交互变革丨Voice Agent 学习笔记
  • Matlab裁剪降水数据:1km掩膜制作实战
  • 从Markdown到PPT:用Python打造专业演示文稿转换器