概述
文章目录
- 二、 语法
- 1. 获取数据
- 2. 修改数据
- 三、模块化
- 四、异步解决
- 1. 问题
- 2. redux-thunk
## 一、 基本配置
- 安装 redux 和 react-redux
npm i redux react-redux --save
- src 下创建 store 目录,新建 index.ts
// 导入 redux 中的 legacy_createStore 来创建状态管理仓库
import { legacy_createStore} from "redux";
import reducer from "./reducer";
// window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
让浏览器redux-dev-tools能正常使用
const store = legacy_createStore(reducer,window.__REDUX_DEVTOOLS_EXTENSION__ &&
window.__REDUX_DEVTOOLS_EXTENSION__());
export default store
- 创建一个提供数据的 reducer.tsx
// 初始化 state
const initialState = {
num: 20,
}
export default (state = initialState) => {
// 将传递的数据进行深拷贝
let newState = JSON.parse(JSON.stringify(initialState))
// 返回 state
return newState
}
- main.tsx 文件中通过 Provider 组件进行包裹 App 组件进行提供数据
// 通过 provider 提供数据
import { Provider } from 'react-redux'
import store from '@/store'
ReactDOM.createRoot(document.getElementById('root') as HTMLElement).render(
// Provider 给所有组件提供 store 里的数据
<Provider store={store}>
<React.StrictMode>
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
</Provider>,
)
二、 语法
1. 获取数据
import { useSelector } from 'react-redux'
// 通过 useSelector 方法,获取返回的 state 中的数据
const { num } = useSelector((state: { num: number }) => ({ num: state.num }))
2. 修改数据
// reducer.tsx
export default (state = initialState, action: { type: string; val: any }) => {
// 将传递的数据进行深拷贝
let newState = JSON.parse(JSON.stringify(state))
// 根据传递的标记执行对应的操作
switch (action.type) {
case 'add':
newState.num++
break
case 'add2':
newState.num += action.val
break
default:
break
}
// 返回 state
return newState
}
// page.tsx
import { useSelector, useDispatch } from 'react-redux'
// 通过 useDispatch 方法,修改 state 中的数据
const dispatch = useDispatch()
const changeNum = () => {
// type 固定属性对应触发的函数名
// val 自定义的属性
// 该方法执行后 reducer 中的会对传递的 type 值进行判断执行对应的操作
// dispatch({ type: 'add' })
dispatch({ type: 'add2', val: 7 })
}
三、模块化
- store 文件夹下创建对应的模块文件夹
- 模块文件下创建 index(管理数据)和 reducer(处理数据) 文件
// 模块1 index
const store = {
state: {
num: 18,
},
actions: {
add(state: { num: any }, action: object) {
state.num++
},
},
}
export default store
// 模块2 index
const store = {
state: {
num: 20,
},
actions: {
add2(state: { num: any }, { type, val }: any) {
state.num += val
},
},
}
export default store
// reducer
import store from '.'
export default (
state = { ...store.state },
action: { type: string; val: any },
) => {
// 将传递的数据进行深拷贝
let newState = JSON.parse(JSON.stringify(state))
// 遍历存储的方法
for (let key in store.actions) {
// 判断传递的方法在 store 中是否存在
if (action.type === key) {
// 存在则调用对应的方法
store.actions[key](newState, action)
break
}
}
// 返回 state
return newState
}
- store 文件夹下的 index 文件将模块进行整合、注册
import { combineReducers, legacy_createStore } from 'redux'
// reducer 导入准备的数据
import reducer1 from './Data/reducer'
import reducer2 from './Data1/reducer'
// 组个各个模块的 reducer
const reducers = combineReducers({
reducer1,
reducer2,
})
// 创建数据仓库,注册 reducer
const store = legacy_createStore(
reducers,
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__(),
)
// 导出
export default store
- 访问的话通过 useSelector 方法返回对应 模块 的数据(state.模块名.xxx)
// 通过 useSelector 方法,获取返回的 state 中的数据
const { num } = useSelector((state: RootState) => ({
// 模块1的 num
num: state.reducer1.num,
}))
const { num: num2 } = useSelector((state: RootState) => ({
// 模块2的 num
num: state.reducer2.num,
}))
四、异步解决
1. 问题
- 在store/NumStatus/index.ts中做异步操作
- 会发现这种写法其实达不到想要的异步效果
- 需要通过 redux 相关的异步方案来解决
add1(newState:{num:number},action:{type:string}){
//newState.num++;
// 会有bug 没有办法达到延迟和修改的效果
setTimeout(()=>{
newState.num++;
},1000)
},
2. redux-thunk
-
市面上有redux- saga , redux-thunk,redux-thunk相比于redux-saga ,体积小,灵活,但需要自己手动抽取和封装。但学习成本较低。
-
安装:npm i redux-thunk
-
让 redux 调式工具兼容异步
-
导入 applyMiddleware、compose 方法将仓库数据、reduxTools、reduxThunk 进行关联
-
给 dispatch 方法传递一个执行异步的回调
-
执行回调中传递的参数,根据 tyep 标记去匹配需要执行的方法
// store/index
import {
combineReducers,
legacy_createStore,
compose,
applyMiddleware,
} from 'redux'
// reducer 导入准备的数据
import reducer1 from './Data/reducer'
import reducer2 from './Data1/reducer'
import reduxThunk from 'redux-thunk'
// 组个各个模块的 reducer
const reducers = combineReducers({
reducer1,
reducer2,
})
// 让 redux 调式工具兼容异步的处理
let composeEnhancers = window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__
? window.__REDUX_DEVTOOLS_EXTENSION_COMPOSE__({})
: compose
// 把仓库数据,浏览器redux-dev-tools,还有reduxThunk插件关联在store中
const store = legacy_createStore(
reducers,
composeEnhancers(applyMiddleware(reduxThunk)),
)
// 导出
export default store
// page
import store from '@/store/Data'
// 异步的写法
redux-thunk 的用法
dispatch(异步执行的函数)
// disp 相当于 dispatch 用来标记调用的函数
// dispatch((disp: Function) => {
//
setTimeout(() => {
//
disp({ type: 'add' })
//
}, 0)
// })
// 优化 redux-thunk 的异步方法
// dispatch(调用状态管理中的 asyncAdd)
dispatch(store.asyncFun.asyncAdd)
// Data/index
{
state: {
num: 18,
},
actions: {
add(state: { num: number }, action: object) {
state.num++
},
},
// 优化 redux-thunk 的异步方法(模仿 vuex 写法 )
// 存放异步的方法
asyncFun: {
asyncAdd(disp: Function) {
setTimeout(() => {
disp({ type: 'add' })
}, 1000)
},
},
}
最后
以上就是细腻星星为你收集整理的【Redux】的封装以及使用(6)的全部内容,希望文章能够帮你解决【Redux】的封装以及使用(6)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复