引言
📒📒📒欢迎来到小冷的代码学习世界
博主的微信公众号 : 想全栈的小冷,分享一些技术上的文章,以及解决问题的经验
⏩当前专栏:react系列
Redux
完整代码案例仓库 :https://gitee.com/cold-abyss_admin/react-redux-meituan
Redux是 React 最常用的集中状态管理工具,类似与VUE的pinia(vuex) 可以独立于框架运行

使用思路:
- 定义一个
reducer函数 根据当前想要做的修改返回一个新的状态 - 使用createStore方法传入reducer函数 生成一个store实例对象
- subscribe方法 订阅数据的变化(数据一旦变化,可以得到通知)
- dispatch方法提交action对象 告诉reducer你想怎么改数据
- getstate方法 获取最新的状态数据更新到视图中

配置Redux
在React中使用redux,官方要求安装俩个其他插件-和react-redux
官方推荐我们使用 RTK(ReduxToolkit) 这是一套工具集合 可以简化书写方式
- 简化store配置
- 内置immer可变式状态修改
- 内置thunk更好的异步创建
调试工具安装
谷歌浏览器搜索 redux-devtool安装 工具
依赖安装
#redux工具包
npm i @reduxjs/toolkit react-redux
#调试工具包
npm install --save-dev redux-devtools-extension

store目录机构设计
- 通常集中状态管理的部分都会单独创建一个
store目录 - 应用通常会有多个子store模块,所以创建一个
modules进行内部业务的区分 - store中的入口文件index.js 的作用是组合所有
modules的子模块 并且导出store

快速上手
使用react+redux 开发一个计数器 熟悉一下技术

-
使用
Reacttoolkit创建 counterStoreimport { createSlice} from "@reduxjs/toolkit"; const counterStore= createSlice({ name: "counter", // 初始化 state initialState: { count: 0 }, // 修改状态的方法 reducers:{ increment(state){ state.count++ }, decrement(state){ state.count-- } } }) // 解构函数 const { increment,decrement}= counterStore.actions // 获取reducer const reducer = counterStore.reducer; export { increment,decrement} export default reducer -
在
index.js集合counterimport { configureStore} from "@reduxjs/toolkit"; import counterStore from "./modules/counterStore"; const store = configureStore({ reducer:{ couner: counterStore, } }) export default store -
为React 注入
store,react-redux负责把Redux和React链接 起来,内置Provider组件 通过store参数把创建好的store实例注入到应用中 找到项目中的index.jsconst root = ReactDOM.createRoot(document.getElementById('root')); root.render( <React.StrictMode> <Provider store={store}> <App /> </Provider> </React.StrictMode> ); -
使用useSelector 获取到数据
import {useSelector} from "react-redux"; function App() { const {count} = useSelector(state => state.counter); return ( <div className="App"> {count} </div> ); } -
使用 钩子函数
useDispatchimport { useDispatch, useSelector} from "react-redux"; import { inscrement,descrement} from "./store/modules/counterStore" function App() { const { count} = useSelector(state => state.counter); const dispatch = useDispatch() return ( <div className="App"> <button onClick={ ()=>dispatch(inscrement())}>+</button> { count} <button onClick={ ()=>dispatch(descrement())}>-</button> </div> ); } export default App; -
查看效果

提交acntion传参
在reducers的同步修改方法中添加action对象参数,在调用actionCreater参数的时候传递参数,参数会被传递到action对象的payload属性上
我们继续的改造一下counterStore
action这个对象参数有个固定的属性叫payload用来接收传参

然后 app.js 添加两个按钮 用来传递参数

效果

Reudx action异步操作
区分同步和异步action

如果action的内容是 object对象那就是同步action,如果是函数 那就是异步action
为什么我们需要异步action操作来使用请求 ?
例子:
我们有两种方式可以实现 隔五分钟 上蛋炒饭
一种是客人自己思考五分钟
一种是客人点好 叫服务员五分钟之后上
这个服务员就是 redux 我们刚希望相关aciton的操作都在redux里完成这个时候同步action就不能满足我们的需求了 所以需要使用异步action
异步操作的代码变化不大,我们创建store的写法保持不变 ,但是在函数中用异步操作的时候需要一个能异步执行函数return出一个新的函数而我们的异步操作卸载新的函数中.
异步action中一般都会调用一个同步action
案例: 从后端获取到列表展示到页面
新建一个文件叫做 ChannelStore.js 然后编写对应的创建代码
import {
createSlice} from "@reduxjs/toolkit";
import axios from "axios";
const channelStore = createSlice({
name: "channel",
initialState: {
channelList:[]
},
reducers:{
setChannel(state, action){
state.channelList=action.payload
}
}
})
const {
setChannel}= channelStore.actions
// 异步请求
const fetchChannelList = ()=>{
return async (dispatch)=>{
const res = await axios.get('http://geek.itheima.net/v1_0/channels')
dispatch(setChannel(res.data.data.channels))
}
}
const reducer = channelStore.reducer;
export {
fetchChannelList}
export default reducer
然后去store入口加入channelStore
import {
configureStore} from "@reduxjs/toolkit";
import counterStore from "./modules/counterStore";
import channelStore from "./modules/channelStore";
const store = configureStore({
reducer:{
counter: counterStore,
channel: channelStore,
}
})
export default store
之后就可以在app.js加入代码
import {useDispatch, useSelector} from "react-redux";
import {useEffect} from "react";
import {fetchChannelList} from "./store/modules/channelStore";
function App() {
const {channelList} = useSelector(state => state.channel);
const dispatch = useDispatch()
useEffect(() => {
dispatch(fetchChannelList())
}, [dispatch]);
return (
<div className="App">
<ul>
{channelList.map(item =><li key={item.id}>{item.name}</li>)}
</ul>
</div>
);
}
export default App;
代码效果

redux hooks
useSelector
它的作用是吧store中的数据映射到组件中
const {
count} = useSelector(state => state.counter);
这里的count其实对应的就是

useDispatch
它的作用是生成提交 action对象的dispatch函数
import {
useDispatch, useSelector} from "react-redux";
import {
inscrement,descrement} from "./store/modules/counterStore"
function App() {
const {
count} = useSelector(state => state.counter);
const dispatch = useDispatch()
return (
<div className="App">
<button onClick={
()=>dispatch(inscrement())}>+</button>
{
count}
<button onClick={
()=>dispatch(descrement())}>-</button>
</div>
);
}
export default App;
美团点餐界面小案例
下载模板地址:
git clone http://git.itcast.cn/heimaqianduan/redux-meituan.git

最低0.47元/天 解锁文章
444

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



