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

在 Next 14 的 appRouter 模式中接入 React-Redux

在 Next 14 的 appRouter 模式中接入 React-Redux

说明

Next.js 版本升级到 14 后,相比 13 版本是一个改动很大的大版本升级,很多概念或者使用方式 13 版本都有较大的区别,因此这里记录一些学习 14 版本的 Next.js 的心得体会或者问题。因为我这边构建项目选择的是 Next.js 新的路由模式 App Router,因此该文档是基于 App Router 路由模式的。

安装依赖

根据 react-redux 官方文档 的说明,使用如下面命令安装依赖:

pnpm add @reduxjs/toolkit react-redux

创建 store 模块

我们以创建一个 counterSlice 举例:
在项目根目录(或者 app 目录,或者其他目录),创建 store 目录,以及 react-redux 的主文件 store.ts,然后创建 /storemodules/counterSlice.ts,并写入如下代码:

//counterSlice.jsx"use client"; //this is a client side componentimport { createSlice } from "@reduxjs/toolkit";
import { RootState } from "../store";const initialState = {value: 0,
};export const counterSlice = createSlice({name: "counter",initialState,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;export const selectCounter = (state: RootState) => state.counter.value;

**注意:**这里需要注意,在 next 中,redux 需要作为客户端渲染的模块,因此 store 模块的文件头部都需要加上使用客户端渲染的注解 "use client";
然后在 store.ts 里面写入如下代码:

//store.jsx"use client";
import { combineReducers, configureStore } from "@reduxjs/toolkit";
import counterReducer from "./modules/counterSlice";
import { Provider } from "react-redux";const rootReducer = combineReducers({counter: counterReducer,//add all your reducers here
});export const store = configureStore({reducer: rootReducer,
});export function ReduxProvider({ children }) {return <Provider store={store}>{children}</Provider>;
}export type RootState = ReturnType<typeof store.getState>;export type AppDispatch = typeof store.dispatch;

ReduxProvider作为组件抛出去。

使用定义好的 store 模块

注册 Provider

我们可以在全局 layout 里面注册 Provider, 这样能保证我们的所有的客户端组件都能使用 Redux:

import type { Metadata } from "next";
import { Inter } from "next/font/google";
import ThemeRegistry from "@/app/components/themeRegistry/ThemeRegistry";
import HeaderBar from "@/app/components/layout/HeaderBar";
import { ReduxProvider } from "@/app/store/store";
import { useEffect } from "react";const inter = Inter({ subsets: ["latin"] });export const metadata: Metadata = {title: "Create Next App11",description: "Generated by create next app",
};function RootLayout({ children }: { children: React.ReactNode }) {return (<html lang="en"><body className={inter.className}><ReduxProvider><ThemeRegistry><HeaderBar />{children}</ThemeRegistry></ReduxProvider></body></html>);
}// export default wrapper.withRedux(RootLayout);
export default RootLayout;

组件中使用 redux

之前已经说了,reduxnext.js 中只能是作为客户端渲染模块使用,所以我们不能再任何的 page.tsx 路由页面组件中使用(除非这个路由页面有客户端渲染组件注解use client;,然而这种情况可能并不多见。),因此对于需要使用 redux 的地方,我们需要这块儿逻辑封装成客户端渲染的组件,比如:

"use client";
import {decrement,increment,selectCounter,
} from "@/app/store/modules/counterSlice";
import { AppDispatch } from "@/app/store/store";
import { Box, Button, Typography } from "@mui/material";
import { useDispatch, useSelector } from "react-redux";export default function CounterControl() {const counter = useSelector(selectCounter);const dispatch = useDispatch<AppDispatch>();const handleChangeCounter = (type: "ADD" | "MINUS") => {dispatch(type === "ADD" ? increment() : decrement());};return (<Box><Typography variant="h1">{counter}</Typography><Box><Button variant="outlined" onClick={() => handleChangeCounter("ADD")}>ADD</Button><Buttonvariant="outlined"onClick={() => handleChangeCounter("MINUS")}sx={{ ml: 2 }}>MINUS</Button></Box></Box>);
}

这样子我们就可以在任意组件(包括路由组件 page.tsx)里面使用封装的这个 CounterControl 组件了:

import { Metadata } from "next";
import { Button } from "@mui/material";
import NavigateButton from "@/app/components/tools/NavigateButton";
import CounterControl from "../components/counter/CounterControl";export const metadata: Metadata = {title: "Users page",description: "Generated by create next app",
};export default function UsersPage() {return (<div><CounterControl /><Button sx={{ mx: 1 }} variant="contained">Hellow Mui</Button><NavigateButton destination="/" variant="contained" sx={{ mx: 2 }}>back</NavigateButton><h2>This is the User Index page</h2></div>);
}

以上就完成了在 Next.js 14App Router 路由模式中接入 react-redux 的全过程。

相关文章:

在 Next 14 的 appRouter 模式中接入 React-Redux

在 Next 14 的 appRouter 模式中接入 React-Redux 说明 Next.js 版本升级到 14 后&#xff0c;相比 13 版本是一个改动很大的大版本升级&#xff0c;很多概念或者使用方式 13 版本都有较大的区别&#xff0c;因此这里记录一些学习 14 版本的 Next.js 的心得体会或者问题。因为…...

aspose-words 跳过证书验证jar

优先用 aspose-words-19.3.jar &#xff0c;不需要读取license.xml&#xff0c;导出后直接水印&#xff0c;jar包最好直接放在项目resource目录下直接引用&#xff0c;要不下载不下来 public static String doc2pdf(String fileName, String filePath) {try {String oldFile f…...

【开题报告】基于uniapp的瑜伽学习交流小程序的设计与实现

1.选题背景 瑜伽在现代社会中越来越受到人们的关注和喜爱。它不仅可以帮助人们塑造健美的身材&#xff0c;还能促进身心健康、提高生活质量。然而&#xff0c;由于瑜伽动作的复杂性和技巧性&#xff0c;很多初学者在学习过程中会遇到困难和挑战。 同时&#xff0c;由于工作和…...

【蓝桥杯单片机】应用手势传感器(串口2)

手势传感器:串口通信,可以识别左滑、右滑、单击三种手势,输出相应的固定串口数据。 控制器:IAP15F2K61S2单片机。 引脚连接: 单片机 手势传感器 P46 -> TX P47 -> RX VCC -> 5V GND->gnd main.c 程序说明:传感器与单片机的串口2进行数据交互,这里使用的是开…...

51单片机蜂鸣器发出悦耳的声音

51单片机蜂鸣器发出悦耳的声音 1.概述 这篇文章介绍单片机控制蜂鸣器入门小实验&#xff0c;通过该实验掌握蜂鸣器发声的原理&#xff0c;控制声音发出我们想听的音乐。 2.蜂鸣器发声 2.1.硬件原理 1.蜂鸣器正极接单片机20号引脚VCC&#xff0c;负极接19号引脚P1.7 2.20MH…...

Web3.0时代:区块链DAPP将如何颠覆传统模式

小编介绍&#xff1a;10年专注商业模式设计及软件开发&#xff0c;擅长企业生态商业模式&#xff0c;商业零售会员增长裂变模式策划、商业闭环模式设计及方案落地&#xff1b;扶持10余个电商平台做到营收过千万&#xff0c;数百个平台达到百万会员&#xff0c;欢迎咨询。 随着…...

JAVA 算法面试总结

1、二分查找 二分查找又叫折半查找&#xff0c;要求待查找的序列有序。每次取中间位置的值与待查关键字比较&#xff0c;如果中间位置 的值比待查关键字大&#xff0c;则在前半部分循环这个查找的过程&#xff0c;如果中间位置的值比待查关键字小&#xff0c; 则在后半部分循环…...

【Docker】安装MySQL 通俗易懂 亲测没有任何问题

目录 1.拉取镜像 2.运行容器 3.创建mysql配置文件 4.测试 1.拉取镜像 dockerhub官网&#xff1a;Docker 如果需要其他版本mysql docker pull mysql:xxx&#xff08;版本&#xff09; docker pull mysql #默认拉取最新版本 latest 2.运行容器 docker run -d -p 3306:33…...

【React】打包优化-配置CDN

CDN 是一种内容分发网络服务&#xff0c;当用户请求网站内容时&#xff0c;由离用户最近的服务器将缓存的资源内容传递给用户。 哪些资源可以放到CDN服务器&#xff1f;&#xff08;比如react、 react-dom&#xff09; 体积较大&#xff0c;需要利用CDN文件在浏览器的缓存特性…...

上手 Promethus - 开源监控、报警工具包

名词解释 Promethus 是什么 开源的【系统监控和警报】工具包 专注于&#xff1a; 1&#xff09;可靠的实时监控 2&#xff09;收集时间序列数据 3&#xff09;提供强大的查询语言&#xff08;PromQL&#xff09;&#xff0c;用于分析这些数据 功能&#xff1a; 1&#xff0…...

Linux学习教程(第十二章 Linux系统管理)三

第十二章 Linux系统管理&#xff08;进程管理、工作管理和系统定时任务&#xff09;&#xff08;三&#xff09; 十九、Linux 定时执行任务&#xff08;at命令&#xff09; Linux at命令详解&#xff1a;定时执行任务 要想使用 at 命令&#xff0c;读者需提前安装好 at 软件…...

网络篇---第三篇

系列文章目录 文章目录 系列文章目录前言一、说一下HTTP的长连接与短连接的区别二、TCP 为什么要三次握手,两次不行吗?为什么?三、说一下 TCP 粘包是怎么产生的?怎么解决粘包问题的?前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大…...

tensorflow和pytorch的联系与区别

TensorFlow和PyTorch是两个流行的深度学习框架&#xff0c;它们在很多方面都有相似之处&#xff0c;因为它们都旨在解决相同的问题&#xff0c;即构建和训练神经网络。 以下是它们之间的一些联系&#xff1a; 1.深度学习框架&#xff1a; TensorFlow和PyTorch都是开源的深度学…...

为什么选择美国VPS服务器

企业、个人和组织都需要一个稳定高效的服务器来托管他们的网站、应用程序和数据。而对于中国用户来说&#xff0c;寻找一个性价比高的便宜美国VPS服务器&#xff0c;既能满足需求&#xff0c;又能节约成本&#xff0c;成为了一个非常重要的问题。 VPS即虚拟专用服务器&#xf…...

StarRocks Evolution:One Data,All Analytics

在 11 月 17 日举行的 StarRocks Summit 2023上&#xff0c;StarRocks TSC Member、镜舟科技 CTO 张友东详细介绍了 StarRocks 社区的发展情况&#xff0c;并全面解析了 StarRocks 的核心技术与未来规划&#xff1b;我们特意将他的精彩演讲整理出来&#xff0c;以帮助大家更深入…...

微信小程序富文本拓展rich-text

微信小程序富文本插件 功能介绍 支持解析<style>标签中的全局样式支持自定义默认的标签样式支持自动设置标题 若html中存在title标签,将自动把title标签的内容设置到页面的标题上,并在回调bindparse中返回,可以用于转发支持添加加载提示 可以在Parser标签内添加加载提…...

Postman:专业API测试工具,提升Mac用户体验

如果你是一名开发人员或测试工程师&#xff0c;那么你一定知道Postman。这是一个广泛使用的API测试工具&#xff0c;适用于Windows、Mac和Linux系统。今天&#xff0c;我们要重点介绍Postman的Mac版本&#xff0c;以及为什么它是你进行API测试的理想选择。 一、强大的功能和易…...

3.golang数组以及切片

数组 数组的声明 数组是具有相同 唯一类型 的一组以编号且长度固定的数据项序列。一个数组的表示形式为 T[n]。n 表示数组中元素的数量&#xff0c;T 代表每个元素的类型。 var a [3]int fmt.Println(a)var a[3]int 声明了一个长度为 3 的整型数组。数组中的所有元素都被自动…...

ElasticSearch02

ElasticSearch客户端操作 ElasticSearch 版本&#xff1a;7.8 学习视频&#xff1a;尚硅谷 笔记&#xff1a;https://zgtsky.top/ 实际开发中&#xff0c;主要有三种方式可以作为elasticsearch服务的客户端&#xff1a; 第一种&#xff0c;使用elasticsearch提供的Restful接口…...

比特币挖矿过程,双花攻击,女巫攻击,DID聚合身份

目录 比特币挖矿过程 双花攻击 双花攻击的原理 双花攻击的类型 双花攻击防范措施:...

黑马Mybatis

Mybatis 表现层&#xff1a;页面展示 业务层&#xff1a;逻辑处理 持久层&#xff1a;持久数据化保存 在这里插入图片描述 Mybatis快速入门 ![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/6501c2109c4442118ceb6014725e48e4.png //logback.xml <?xml ver…...

OkHttp 中实现断点续传 demo

在 OkHttp 中实现断点续传主要通过以下步骤完成&#xff0c;核心是利用 HTTP 协议的 Range 请求头指定下载范围&#xff1a; 实现原理 Range 请求头&#xff1a;向服务器请求文件的特定字节范围&#xff08;如 Range: bytes1024-&#xff09; 本地文件记录&#xff1a;保存已…...

TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案

一、TRS收益互换的本质与业务逻辑 &#xff08;一&#xff09;概念解析 TRS&#xff08;Total Return Swap&#xff09;收益互换是一种金融衍生工具&#xff0c;指交易双方约定在未来一定期限内&#xff0c;基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

学校时钟系统,标准考场时钟系统,AI亮相2025高考,赛思时钟系统为教育公平筑起“精准防线”

2025年#高考 将在近日拉开帷幕&#xff0c;#AI 监考一度冲上热搜。当AI深度融入高考&#xff0c;#时间同步 不再是辅助功能&#xff0c;而是决定AI监考系统成败的“生命线”。 AI亮相2025高考&#xff0c;40种异常行为0.5秒精准识别 2025年高考即将拉开帷幕&#xff0c;江西、…...

Mobile ALOHA全身模仿学习

一、题目 Mobile ALOHA&#xff1a;通过低成本全身远程操作学习双手移动操作 传统模仿学习&#xff08;Imitation Learning&#xff09;缺点&#xff1a;聚焦与桌面操作&#xff0c;缺乏通用任务所需的移动性和灵活性 本论文优点&#xff1a;&#xff08;1&#xff09;在ALOHA…...

安卓基础(aar)

重新设置java21的环境&#xff0c;临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的&#xff1a; MyApp/ ├── app/ …...

GitFlow 工作模式(详解)

今天再学项目的过程中遇到使用gitflow模式管理代码&#xff0c;因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存&#xff0c;无论是github还是gittee&#xff0c;都是一种基于git去保存代码的形式&#xff0c;这样保存代码…...

jmeter聚合报告中参数详解

sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample&#xff08;样本数&#xff09; 表示测试中发送的请求数量&#xff0c;即测试执行了多少次请求。 单位&#xff0c;以个或者次数表示。 示例&#xff1a;…...

Web后端基础(基础知识)

BS架构&#xff1a;Browser/Server&#xff0c;浏览器/服务器架构模式。客户端只需要浏览器&#xff0c;应用程序的逻辑和数据都存储在服务端。 优点&#xff1a;维护方便缺点&#xff1a;体验一般 CS架构&#xff1a;Client/Server&#xff0c;客户端/服务器架构模式。需要单独…...

在树莓派上添加音频输入设备的几种方法

在树莓派上添加音频输入设备可以通过以下步骤完成&#xff0c;具体方法取决于设备类型&#xff08;如USB麦克风、3.5mm接口麦克风或HDMI音频输入&#xff09;。以下是详细指南&#xff1a; 1. 连接音频输入设备 USB麦克风/声卡&#xff1a;直接插入树莓派的USB接口。3.5mm麦克…...