react19+nextjs+antd切換主題顏色

在 React 19 + Next.js + Ant Design 項目中實現主題切換功能,可以通過以下步驟完成。這里將提供完整方案,包含靜態主題切換和動態實時切換兩種方式。


一、基礎配置(Ant Design 主題支持)

1. 安裝必要依賴
npm install antd @ant-design/cssinjs
2. 配置 Next.js 支持 CSS-in-JS

修改 next.config.js

/** @type {import('next').NextConfig} */
const nextConfig = {experimental: {appDir: true,},transpilePackages: ['antd'],
};module.exports = nextConfig;
3. 創建主題配置文件

src/theme/themeConfig.ts

import type { ThemeConfig } from 'antd';// 基礎主題配置
export const baseTheme: ThemeConfig = {token: {colorPrimary: '#1677ff',borderRadius: 6,},
};// 暗黑主題
export const darkTheme: ThemeConfig = {token: {...baseTheme.token,colorBgBase: '#141414',colorTextBase: '#f0f0f0',colorPrimary: '#177ddc',},algorithm: 'dark',
};// 自定義主題
export const customTheme: ThemeConfig = {token: {...baseTheme.token,colorPrimary: '#ff4d4f',},
};

二、靜態主題切換方案(SSR 兼容)

1. 創建 ThemeProvider 組件

src/providers/ThemeProvider.tsx

'use client';import { ReactNode, useState } from 'react';
import { ConfigProvider, theme } from 'antd';
import { baseTheme, darkTheme, customTheme } from '@/theme/themeConfig';type ThemeType = 'light' | 'dark' | 'custom';export function ThemeProvider({ children }: { children: ReactNode }) {const [currentTheme, setCurrentTheme] = useState<ThemeType>('light');const getThemeConfig = () => {switch (currentTheme) {case 'dark':return darkTheme;case 'custom':return customTheme;default:return baseTheme;}};return (<ConfigProvider theme={getThemeConfig()}>{children}{/* 主題切換控件可以放在這里 */}</ConfigProvider>);
}
2. 在布局文件中使用

src/app/layout.tsx

import { ThemeProvider } from '@/providers/ThemeProvider';export default function RootLayout({children,
}: {children: React.ReactNode
}) {return (<html lang="en"><body><ThemeProvider>{children}</ThemeProvider></body></html>);
}

三、動態實時切換方案(含持久化)

1. 擴展 ThemeProvider
'use client';import { ReactNode, useEffect, useState } from 'react';
import { ConfigProvider, theme } from 'antd';
import { baseTheme, darkTheme, customTheme } from '@/theme/themeConfig';type ThemeType = 'light' | 'dark' | 'custom';export function ThemeProvider({ children }: { children: ReactNode }) {const [currentTheme, setCurrentTheme] = useState<ThemeType>('light');// 初始化時讀取本地存儲useEffect(() => {const savedTheme = localStorage.getItem('theme') as ThemeType || 'light';setCurrentTheme(savedTheme);}, []);// 主題變化時保存到本地存儲useEffect(() => {localStorage.setItem('theme', currentTheme);document.documentElement.setAttribute('data-theme', currentTheme);}, [currentTheme]);const getThemeConfig = () => {switch (currentTheme) {case 'dark':return darkTheme;case 'custom':return customTheme;default:return baseTheme;}};const toggleTheme = () => {setCurrentTheme(prev => {if (prev === 'light') return 'dark';if (prev === 'dark') return 'custom';return 'light';});};return (<ConfigProvider theme={getThemeConfig()}>{children}<button onClick={toggleTheme}style={{ position: 'fixed', right: 20, bottom: 20 }}>切換主題</button></ConfigProvider>);
}
2. 添加全局 CSS 變量

src/app/globals.css

:root {--primary-color: #1677ff;
}[data-theme="dark"] {--primary-color: #177ddc;
}[data-theme="custom"] {--primary-color: #ff4d4f;
}

四、高級功能擴展

1. 主題色選擇器
import { ColorPicker } from 'antd';function ThemeColorPicker() {const [color, setColor] = useState('#1677ff');return (<ConfigProvidertheme={{token: {colorPrimary: color,},}}><ColorPicker value={color} onChangeComplete={(color) => setColor(color.toHexString())}/></ConfigProvider>);
}
2. 使用 CSS 變量動態主題
// 在 ThemeProvider 中添加
useEffect(() => {document.documentElement.style.setProperty('--primary-color', getThemeConfig().token.colorPrimary);
}, [currentTheme]);

五、解決 Next.js 的 SSR 問題

1. 創建 useClientTheme Hook

src/hooks/useClientTheme.ts

'use client';import { useEffect, useState } from 'react';export function useClientTheme() {const [theme, setTheme] = useState<'light' | 'dark'>('light');useEffect(() => {// 只在客戶端執行const savedTheme = localStorage.getItem('theme') || 'light';setTheme(savedTheme as 'light' | 'dark');}, []);return theme;
}
2. 修改組件使用方式
'use client';import { useClientTheme } from '@/hooks/useClientTheme';export default function ClientComponent() {const theme = useClientTheme();return (<div data-theme={theme}>{/* 內容 */}</div>);
}

六、完整實現流程圖

UserUIThemeProviderLocalStorageConfigProvider點擊切換主題按鈕調用toggleTheme()保存新主題更新主題配置重新渲染應用樣式顯示新主題界面UserUIThemeProviderLocalStorageConfigProvider

七、最佳實踐建議

  1. 性能優化

    • 使用 React.memo 避免不必要的重渲染
    • 將主題狀態提升到最頂層組件
  2. TypeScript 強化

    type ThemeType = 'light' | 'dark' | 'custom';
    interface ThemeContextType {theme: ThemeType;setTheme: (theme: ThemeType) => void;
    }
    
  3. 服務端渲染兼容

    • 使用 dynamic 導入客戶端組件
    • _document.tsx 中初始化主題
  4. 測試方案

    // 測試主題切換
    test('should toggle theme correctly', () => {render(<ThemeProvider />);const button = screen.getByText('切換主題');fireEvent.click(button);expect(localStorage.getItem('theme')).toBe('dark');
    });
    

通過以上方案,你可以實現一個完整、高效且可維護的主題切換系統,同時兼容 Next.js 的服務端渲染特性。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/915347.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/915347.shtml
英文地址,請注明出處:http://en.pswp.cn/news/915347.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Modbus Slave 使用教程:快速搭建模擬從站進行測試與開發

文章目錄Modbus Slave 使用教程&#xff1a;快速搭建模擬從站進行測試與開發步驟詳解&#xff1a;搭建 Modbus Slave1. 安裝與啟動2. 配置從站連接 (Connection Setup)連接3. 定義從站數據 (設置寄存器/線圈映射)4. 設置初始值與變化模式 (可選但重要)5. 連接 Master 進行測試高…

通俗易懂神經網絡:從基礎到實現

引言 神經網絡是人工智能和深度學習的核心&#xff0c;它模仿人腦的工作方式&#xff0c;通過數據學習復雜的模式。本文將以通俗易懂的方式講解神經網絡的基礎知識&#xff0c;包括單層神經網絡、多層神經網絡&#xff0c;最后用Python代碼實現一個簡單的神經網絡模型。1. 神經…

【Linux】基本指令詳解(三) 指令本質、三個查找指令、打包壓縮、重要熱鍵、linux體系結構、命令行解釋器

文章目錄date指令cal指令find指令(指令本質也是文件)which指令file指令whereis指令alias指令grep指令top指令打包和壓縮指令zip/unzip指令關于rzsz(linux與windows互傳 )tar指令linux機器之間互傳bc指令uname指令(查看linux機器體系結構)幾個重要的熱鍵[Tab]按鍵[Ctrl]c按鍵[Ct…

MSTP 多生成樹協議

MSTP 多生成樹協議 STP/RSTP 的局限性 所有 vlan 共享一顆生成樹無法實現不同 vlan 在多條 Trunk 鏈路上的分擔 二層鏈路負載均衡STP/RSTP 的局限——次優二層路徑**次優二層路徑&#xff08;Suboptimal Layer 2 Path&#xff09; 是指&#xff1a; ** 數據幀在交換網絡中傳輸時…

Shell腳本-tee工具

一、前言在 Linux/Unix 系統中&#xff0c;tee 是一個非常實用的命令行工具&#xff0c;它可以幫助我們 同時將命令的輸出打印到終端&#xff0c;并寫入文件。這種“雙路輸出”機制在腳本調試、日志記錄、自動化任務中非常有用。無論是做日志分析、腳本調試&#xff0c;還是編寫…

走進Linux的世界:Linux基本指令(三)

嘿&#xff0c;各位技術潮人&#xff01;好久不見甚是想念。生活就像一場奇妙冒險&#xff0c;而編程就是那把超酷的萬能鑰匙。此刻&#xff0c;陽光灑在鍵盤上&#xff0c;靈感在指尖跳躍&#xff0c;讓我們拋開一切束縛&#xff0c;給平淡日子加點料&#xff0c;注入滿滿的pa…

跨域詳解與解決方案:從理論到實踐的全面指南

目錄 1. 跨域是什么?為什么它讓人頭禿? 為什么跨域問題讓人抓狂? 跨域的本質 2. 跨域的罪魁禍首:同源策略與CORS 同源策略的來龍去脈 CORS:跨域的“通行證” 3. JSONP:古老但依然有用的跨域“黑科技” JSONP的原理 JSONP的優缺點 4. 代理服務器:跨域的“中間人…

深入詳解:決策樹在輔助診斷系統與臨床決策支持中的應用及實現細節

?? 博主簡介:CSDN博客專家、CSDN平臺優質創作者,高級開發工程師,數學專業,10年以上C/C++, C#,Java等多種編程語言開發經驗,擁有高級工程師證書;擅長C/C++、C#等開發語言,熟悉Java常用開發技術,能熟練應用常用數據庫SQL server,Oracle,mysql,postgresql等進行開發應用…

【詳細筆記】兩類曲線積分轉換

文章目錄參考教程一兩類曲線積分的聯系參數方程曲線的切線方向余弦參考教程2兩類曲線積分之間的關系物理意義解釋證明思路參考教程一 3分鐘幫你搞定兩類曲線積分之間的聯系&#xff08;弧長和坐標&#xff09; 兩類曲線積分的聯系 設平面曲線LLL上的第二類曲線積分∫LPdxQdy…

【成品設計】基于STM32F429的云端電子相冊

V1《基于STM32F429的云端電子相冊》 V1硬件框圖&#xff1a;V1功能說明&#xff1a; 支持 softAP 配網。支持 HTTPS 客戶端的 GET\POST 請求支持文件系統用于圖片的存儲。支持 LVGL 自定義 GUI。日歷功能。STM32F429文件系統LVGLRGB LCD屏幕。屏幕尺寸480*480. 首次開機交互&am…

網絡安全隔離技術解析:從網閘到光閘的進化之路

目錄 一、網絡安全隔離技術體系 1.1 網絡安全隔離技術發展歷程 1.2 隔離技術分類矩陣 1.3 核心隔離原理對比 二、網閘技術深度解析 2.1 GAP架構剖析&#xff08;Guarded Access Point System 安全隔離與信息交換系統&#xff09; 2.2 技術演進路線 三、光閘技術突破創新…

初識 二叉樹

目錄樹什么是二叉樹二叉樹的五種狀態滿二叉樹完全二叉樹二叉排序樹平衡二叉樹二叉樹的遍歷B3642 二叉樹的遍歷P1305 新二叉樹二叉樹的深度P4913 【深基16.例3】二叉樹深度相關例題訓練&#xff1a;二叉樹問題樹 這是樹&#xff08;拍攝于鄭州輕工業大學&#xff0c;第一次鄭州輕…

(1)Windows環境下安裝Oracle

概述&#xff1a;Oracle數據庫是一種網絡上的數據庫, 它在網絡上支持多用戶, 支持服務器/客戶機等部署(或配置)。服務器與客戶機是軟件概念&#xff1a;它們與計算機硬件不存在一一對應的關系. 即:同一臺計算機既可以充當服務器又可以充當客戶機,或者一臺計算機只充當服務器或只…

工業數據集成中間件工具OPC Router詳細介紹

一、產品概述 OPC Router 是 Software Toolbox 旗下的一款面向工業數據集成與自動化的數據中間件工具&#xff0c;專注于實現各類工業系統之間的數據交互和自動化流程編排。它通過模塊化的插件機制&#xff0c;打通 PLC、ERP、MES、數據庫、MQTT、REST API 等不同系統之間的數…

消息隊列 2.RabbitMQ的基本概念與使用

RabbitMQ 是一款基于 AMQP&#xff08;Advanced Message Queuing Protocol&#xff09;協議的開源消息中間件&#xff0c;主要用于實現分布式系統中的消息傳遞&#xff0c;支持異步通信、系統解耦、流量削峰等場景。在 Java 生態中&#xff0c;RabbitMQ 被廣泛應用&#xff0c;…

【web安全】SQL注入與認證繞過

目錄 一、SQL注入漏洞 1.1 基礎注入原理 1.2 實用注入Payload分類 邏輯繞過型 注釋截斷型 聯合查詢型 常見的萬能密碼-CSDN博客 二、登錄繞過實戰技巧 2.1 基礎繞過手法 2.2 高級繞過技巧 編碼繞過 多重注釋 參數污染 三、密碼重置漏洞利用 3.1 常見漏洞模式 3…

Python適配器模式詳解:讓不兼容的接口協同工作

一、模式定義與核心思想 適配器模式&#xff08;Adapter Pattern&#xff09; 是一種結構型設計模式&#xff0c;它通過創建一個中間層&#xff08;適配器&#xff09;&#xff0c;將不兼容的接口轉換為客戶端期望的接口。就像現實中的電源適配器&#xff0c;讓不同國家的插頭…

微信小程序列表數據上拉加載,下拉刷新

1.上拉加載數據&#xff0c;數據 下一頁數據 前面的數據&#xff08;[...this.data.list, ...data.records&#xff09;2.當用戶上拉加載過快時&#xff0c;會不停的調用接口&#xff0c;需要節流閥isLoading3.上拉加載到最后一頁的判斷&#xff0c;isFinish// pages/list.js…

【樹上倍增 LCA DFS 前綴和】P10391 [藍橋杯 2024 省 A] 零食采購|普及+

本文涉及知識點 C算法&#xff1a;前綴和、前綴乘積、前綴異或的原理、源碼及測試用例 包括課程視頻 CDFS 樹上倍增 LCA P10391 [藍橋杯 2024 省 A] 零食采購 題目描述 小藍準備去星際旅行&#xff0c;出發前想在本星系采購一些零食&#xff0c;星系內有 nnn 顆星球&#x…

PDF發票批量打印工具哪個好?高效打印發票的實用工具推薦

開小超市這幾年&#xff0c;每月要打幾十張進貨發票做賬&#xff0c;以前打印時總犯愁&#xff1a;有的發票 PDF 太大&#xff0c;打出來字小得看不清&#xff1b;有的又太窄&#xff0c;白白浪費半張紙。試過手動調整&#xff0c;每張都要改縮放比例&#xff0c;累不說&#x…