以create-vite生成的 React + TypeScript + SWC 项目为基础总结,但也可为由 npm create @quick-start/electron@latest 生成的electron项目使用
1. 2025/9/18 安装 react-router
采用 Data 模式
官方教程:https://reactrouter.com/start/data/installation
输入npm命令安装 react-router:
npm i react-router
在项目根目录创建文件router.tsx,输入以下内容:
import { createBrowserRouter } from "react-router";
import App from './App.tsx'
import LoginForm from "./components/features/login/loginForm.tsx";
import ForgetAccountForm from "./components/features/login/forgetAccountForm.tsx";
export const router = createBrowserRouter([
{
path: "/",
Component: App,
children: [],
},
{
path: "/login",
element: <div className="flex min-h-svh flex-col items-center justify-center"><LoginForm></LoginForm></div>,
},
{
path: "/forgetpwd/:user?",
loader: async ({ params }) => {
return { value: params.user ?? "" };
},
element: <div className="flex min-h-svh flex-col items-center justify-center"><ForgetAccountForm></ForgetAccountForm></div>,
},
]);
接着在main.tsx里补充这些内容:
// ......
import { RouterProvider } from "react-router/dom";
import { router } from './router.tsx';
// ......
createRoot(document.getElementById('root')!).render(
<StrictMode>
// ......
<RouterProvider router={router}></RouterProvider>
// ......
</StrictMode>,
)
最后说说怎么用:
import { useEffect } from "react";
import { useNavigate } from "react-router";
export default function App() {
// ......
const navigate = useNavigate();
// ......
useEffect(() => {
navigate("/login")
})
}
注意,不要把调用useNavigate()的那句代码放到useEffect里面!
2. 2025/9/19 安装 react-redux
不用 core 的写法,而是用 Toolkit 的写法
建议安装浏览器拓展以强化开发调试体验:
https://github.com/reduxjs/redux-devtools
官方教程:
https://redux-toolkit.js.org/tutorials/quick-start
https://redux-toolkit.js.org/tutorials/typescript
输入npm命令安装 react-redux 和它的 toolkit:
npm install @reduxjs/toolkit react-redux
基于项目的文件目录布局,在对应目录创建针对某一个持久化变量的slice文件,如countSlice.tsx:
import { createSlice, type PayloadAction } from '@reduxjs/toolkit'
interface CounterState {
val: number
}
const initialState: CounterState = {
val: 0,
}
export const countSlice = createSlice({
name: "count",
initialState,
reducers: {
increase: (state) => { state.val++ },
decrease: (state) => { state.val-- },
incrementByAmount: (state, action: PayloadAction<number>) => {
state.val += action.payload
},
}
})
export const { increase, decrease, incrementByAmount } = countSlice.actions
export default countSlice.reducer
在项目根目录创建文件store.tsx,输入以下内容:
(基于原则,一个项目只能有一个store)
import { configureStore } from "@reduxjs/toolkit";
import countReducre from './countSlice'
export const store = configureStore({
reducer: {
count: countReducre
}
})
export type RootState = ReturnType<typeof store.getState>
export type AppDispatch = typeof store.dispatch
接着继续在根目录创建hooks.tsx:
import { useDispatch, useSelector } from 'react-redux'
import type { RootState, AppDispatch } from './store'
export const useAppDispatch = useDispatch.withTypes<AppDispatch>()
export const useAppSelector = useSelector.withTypes<RootState>()
接着在main.tsx里补充这些内容:
// ......
import { Provider } from 'react-redux'
import { store } from './store.tsx';
// ......
createRoot(document.getElementById('root')!).render(
<StrictMode>
// ......
<Provider store={store}>
<RouterProvider router={router}></RouterProvider>
</Provider>
// ......
</StrictMode>,
)
最后说说怎么用:
import { useAppSelector, useAppDispatch } from './hooks'
import { decrease, increase, incrementByAmount } from "./countSlice";
export default function App() {
// ......
const count = useAppSelector((state) => { return state.count.val })
const dispatch = useAppDispatch()
// ......
dispatch(increase())
dispatch(decrease())
dispatch(incrementByAmount(-5))
}
3. 2025/9/19 安装 react-i18next
官方教程:
https://react.i18next.com/getting-started
https://react.i18next.com/guides/quick-start
输入npm命令安装 react-i18next:
npm install react-i18next i18next --save
基于项目的文件目录布局,在对应目录创建针对某一个语言的json文件,如zh-cn.json:
{
"Hi": "你好"
}
或者如en-us.json:
{
"Hi": "Hi"
}
以下是我个人的文件目录布局:
├─assets
│ └─language
│ │ i18n_config.tsx
│ │
│ └─locales
│ en-us.json
│ zh-cn.json
接着创建语言的总管理文件 i18n_config.tsx(名字随意),输入以下内容:
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import en_us from './locales/en-us.json'
import zh_cn from './locales/zh-cn.json'
const resources = {
en: { translation: en_us },
zh: { translation: zh_cn },
};
i18n.use(initReactI18next).init({
resources,
lng: "en",
fallbackLng: "zh",
interpolation: { escapeValue: false }
});
export default i18n;
接着在main.tsx里补充这些内容:
// ......
import i18n from './assets/language/i18n_config.tsx'
import { I18nextProvider } from 'react-i18next';
// ......
createRoot(document.getElementById('root')!).render(
<StrictMode>
// ......
<I18nextProvider i18n={i18n}>
<Provider store={store}>
<RouterProvider router={router}></RouterProvider>
</Provider>
</I18nextProvider>
// ......
</StrictMode>,
)
最后说说怎么用:
import { useTranslation } from "react-i18next";
export default function App() {
// ......
const { t, i18n } = useTranslation();
// ......
return (<>
<Select onValueChange={(val: string) => { i18n.changeLanguage(val) }}>
<SelectTrigger className="w-[180px]">
<SelectValue placeholder="Language" />
</SelectTrigger>
<SelectContent>
<SelectItem value="en">English</SelectItem>
<SelectItem value="zh">简体中文</SelectItem>
</SelectContent>
</Select>
</>)
}
1019

被折叠的 条评论
为什么被折叠?



