Redux
温馨提示
正在学习整理中...
Redux
类似与 Vuex / pinia 状态管理工具
Redux - 中文官网
Redux-中文
Redux-中文
Redux-英文
Redux Toolkit - 官网
公共状态管理工具
- redux + react-redux
- dva(redux-sage) 或 umi
- MobX
- ...
别名@配置
目前的文件结构
// 最新的vite将tsconfig.json分成了三个文件 只需要修改下面的两个文件的配置即可
---tsconfig.app.json // 此文件需要修改
---tsconfig.json
---tsconfig.node.json
---vite.config.ts // 此文件需要修改// vite.config.ts
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
// 路径别名
import { resolve } from 'path'
// https://vite.dev/config/
export default defineConfig({
plugins: [react()],
// 别名的配置
// 当项目的层级比较多是的时候 直接使用@ 就直接到了src目录
resolve: {
alias: {
"@": resolve(__dirname, "./src")
}
}
})// ts版本
// tsconfig.app.json
{
"compilerOptions": {
// 配置别名
"paths":{
"@/*": ["./src/*"],
}
...
}
}// js 版本
// jsconfig.json
{
"compilerOptions": {
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["src/**/*"],
"exclude": ["node_modules"]
}- 下面这种方式不推荐, 除非即使配置了还是没有提示信息, 可以试一试.
VSCode可通过命令面板(ctrl + shift + p)执行“Developer: Reload Window” 清除IDE缓存
VScode别名配置
Path-intellisense 插件
目的: 这样就算没有加一个别名也可以有自动提示了
- 第一步: 选择扩展设置
- 第二步: 打钩 Path-intellisense: Auto Trigger Next Suggestion
- 第三步: 在settings.json中添加以下的配置
{
....
//添加以下配置(主要是前两个)
"path-intellisense.mappings": {
"@/": "${workspaceFolder}/src",
"/": "${workspaceFolder}",
"lib": "${workspaceFolder}/lib",
"global": "/Users/dummy/globalLibs"
},
"path-intellisense.autoTriggerNextSuggestion": true,
}Redux库和工具
- React-Redux
- Redux-Toolkit
- Redux DevTools 扩展
安装 redux
在原生的JS中都可以是使用Redux, React/VUE也可以使用Redux.他是原生的. 由于Vue自己开发了一套状态管理工具Vuex/Pinia
npm install redux- 步骤一: 创建Redux 在src下面创建store, 再在里面创建index.ts
// 创建 Redux
// 步骤一: 导入 Redux 的 createStore 方法
import { createStore } from 'redux'
// 步骤四: reducer 管理员 修改STORE容器里面的公共状态
const initial = { // 默认值
supNum: 0,
oppNum:0
}
const reducer = (state = initial, action: { type: 'VOTE_SUP' | 'VOTE_OPP' }) => {
// 浅克隆
state = { ...state }
// 修改公共的状态
switch (action.type) {
case 'VOTE_SUP':
state.supNum++
break
case 'VOTE_OPP':
state.oppNum++
break
default:
break
}
// 返回最新的sate, 会替换STORE容器中的状态
return state;
}
// 步骤二: 创建STORE容器
const store = createStore(reducer) // reducer 管理员
// 步骤三: 导出 store
export default store;
/**
* 1.在创建的store容器中, 存储两个部分
* a.公共状态: 各组件需要共享/通信的信息
* b.事件池: 存放一些方法[ 让组件可以更新的方法 ]
*
* 特点: 当公共状态一旦发生改变, 会默认立即通知事件池中的方法执行.
* 这些方法的执行, 主要目的就是让指定的组件更新; 而组件一但更新, 就可以获取最新的公共状态信息进行渲染.
*
* 2.修改公共容器中的状态, 不能直接去修改?
* a.基于dispatch派发, 通知 reducer 执行
* b.在 reducer 中去实现状态的更新
*/- 步骤二: 创建上下文对象 在更目录下创建ThemeContext.ts
import React from "react";
// 创建上下文对象
const ThemeContext = React.createContext({}) // 默认值空
// 可以使用redux 类似与vue的vuex/pinia
// 导出创建的对象
export default ThemeContext;- 步骤三: 将创建的上下文挂载到根文件
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import App from './App.tsx'
import { ConfigProvider } from 'antd'; // 国际化
import zhCN from 'antd/locale/zh_CN'; // 国际化 中文
import 'dayjs/locale/zh-cn'; // 国际化 日期
import './index.css'
// 创建上下文
import ThemeContext from './ThemeContext.ts'
// 挂载状态
import store from './store/index.ts';
createRoot(document.getElementById('root')!).render(
<StrictMode>
<ConfigProvider locale={zhCN} >
<ThemeContext.Provider value={store}>
<App />
</ThemeContext.Provider>
</ConfigProvider>
</StrictMode>,
)- 步骤四: 在组件中使用, 在类组件中和Hook函数组件使用的方式有所不同, 下面的案例主要是Hook函数组件
下面的文件尽量使用jsx, 如果使用tsx会有警告, 目前还有去研究它的类型
Vote.jsx
import { useContext , useEffect, useState,} from "react"
import { VoteFooter } from "./VoteFooter"
import { VoteMain } from "./VoteMain"
import styled from "styled-components"
import ThemeContext from "../../../ThemeContext"
// 样式
const VoteDiv = styled.div`
margin: 20px;
width: 350px;
padding: 10px 20px;
border: 1px solid #999;
border-radius: 8px;
`
const VoteHeader = styled.div`
display: flex;
justify-content: space-between;
align-items: center;
span{
color: #f40;
font-size: 30px;
}
`
export const Vote = () => {
// 使用创建的上下文的对象
const store = useContext(ThemeContext)
const { supNum, oppNum } = store.getState()
// 依据redux的流程 若状态改变, 必须更新store的状态池
const [,forceUpdate] = useState(0);
useEffect(() => {
store.subscribe(() => {
forceUpdate(Math.random())
})
})
return <VoteDiv>
<VoteHeader>
<h2>{'React是很棒的前端框架'}</h2>
<span>{oppNum + supNum}</span>
</VoteHeader>
<VoteMain />
<VoteFooter />
</VoteDiv>
}VoteMain.jsx
import {useContext, useEffect, useState} from 'react'
import styled from "styled-components"
import ThemeContext from "../../../ThemeContext"
// 样式
const VoteMainDiv = styled.div`
margin: 15px 0 20px 0;
line-height: 32px;
p{
border-bottom: 1px dotted #999;
display: flex;
justify-content: space-between;
align-items: center;
span{
font-size: 20px;
}
}
`
export const VoteMain = () => {
// 使用创建的上下文的对象
const store = useContext(ThemeContext)
const { supNum, oppNum } = store.getState()
let ratio = '---';
if ((supNum + oppNum) > 0) ratio = (supNum / (supNum + oppNum) * 100).toFixed(2) + '%';
// 依据redux的流程 若状态改变, 必须更新store的状态池
const [,forceUpdate] = useState(0);
useEffect(() => {
store.subscribe(() => {
forceUpdate(Math.random())
})
})
return <VoteMainDiv>
<p>支持人数: <span>{supNum}</span></p>
<p>反对人数: <span>{oppNum}</span></p>
<p>支持比率: <span>{ratio}</span></p>
</VoteMainDiv>
}VoteFooter.jsx
import {useContext} from 'react'
import { Button } from 'antd'
import styled from "styled-components"
import ThemeContext from "../../../ThemeContext"
// 样式
const VoteFooterDiv = styled.div`
display: flex;
justify-content: space-between;
align-items: center;
Button{
width: 150px;
}
`
export const VoteFooter = () => {
// 使用创建的上下文的对象
const store = useContext(ThemeContext)
const handle = (type: 'VOTE_SUP' | 'VOTE_OPP') => {
store.dispatch({type})
}
return <VoteFooterDiv>
<Button type='primary' shape='round' onClick={handle.bind(null,'VOTE_SUP')}>支持</Button>
<Button type='primary' danger shape='round' onClick={handle.bind(null,'VOTE_OPP')}>反持</Button>
</VoteFooterDiv>
}redux 工程化开发
即将redux拆分
/**
* redux工程化的开发:
* 1.创建一个STORE容器
* 2.拆分reducer
* 3.合并reducer
*/
import { combineReducers, createStore } from 'redux';
import { voteReducer } from './voteReducer';
import { personalReducer } from './personalReducer';
const reducer = combineReducers({
vote: voteReducer,
personal:personalReducer
})
const store = createStore(reducer)
export default store;// voteReducer.ts
import _ from '@/utils/index'
const initial = {
supNum: 0,
oppNum: 0
}
export const voteReducer = (state = initial, action: { type: 'VOTE_SUP' | 'VOTE_OPP' }) => {
// 对state进行拷贝
state = _.clone(state, true);
// 修改状态值
switch (action.type) {
case 'VOTE_SUP':
state.supNum++
break
case 'VOTE_OPP':
state.oppNum++
break
default:
break
}
// 将最新的state放回出去
return state
}
// ========================
// personalReducer.ts
import _ from '@/utils/index'
const initial = {
num: 100,
}
export const personalReducer = (state = initial, action: { type: 'VOTE_NUM'}) => {
// 对state进行拷贝
state = _.clone(state, true);
// 修改状态值
switch (action.type) {
case 'VOTE_NUM':
state.num++
break;
default:
break;
}
// 将最新的state放回出去
return state
}安装 @reduxjs/toolkit
下面主要是运用到React里面, 让React的开发更加的简便.
npm install @reduxjs/toolkit react-redux