Redux是React最常用的集中状态管理工具,类似于Vue中的Pinia (Vuex),可以独立于框架运行作用:通过集中管理的方式管理应用的状态
1. 定义一个reducer 数 (根据当前想要做的修改返回一个新的状态)
2. 使用createStore方法传入 reducer函数 生成一个store实例对象
3. 使用store实例的 subscribe方法 订阅数据的变化(数据一旦变化,可以得到通知)
4. 使用store实例的 dispatch方法提交action对象 触发数据变化(告诉reducer你想怎么改数据)
5. 使用store实例的 getstate方法 获取最新的状态数据更新到视图中
注册仓库
store/modules/countStore
import { createSlice } from "@reduxjs/toolkit";
const counterStore = createSlice({
name: "counter",
// 初始化state
initialState: {
count: 100,
},
// 修改数据的方法 同步方法 支持直接修改
reducers: {
inscrement(state) {
state.count++;
},
decrement(state) {
state.count--;
},
addToNum(state, action) {
state.count = action.payload
}
},
});
// 结构出来actionCreater函数
const { inscrement, decrement, addToNum } = counterStore.actions;
// 获取reducer
const reducer = counterStore.reducer;
// 按需导出actionCreater
export { inscrement, decrement, addToNum };
// 默认导出reducer
export default reducer;
store/modules/channelStore 异步请求
import { createSlice } from "@reduxjs/toolkit";
import axios from "axios";
const channelStore = createSlice({
name: "channel",
initialState: {
channelList: [],
},
reducers: {
setChannels(state, action) {
state.channelList = action.payload;
},
},
});
const { setChannels } = channelStore.actions;
// 异步请求
const fetchChannelList = () => {
return async (dispatch) => {
const res = await axios.get("http://geek.itheima.net/v1_0/channels");
dispatch(setChannels(res.data.data.channels));
};
};
export { fetchChannelList };
const reducer = channelStore.reducer
export default reducer
store/index.js
import { configureStore } from "@reduxjs/toolkit";
import counterReducer from './modules/countStore'
import channelReducer from './modules/channelStore'
const store = configureStore({
reducer: {
counter: counterReducer,
channel: channelReducer
}
})
export default store
为react注入store
index.js
// 项目的入口
// React必要的两个核心包
import React from "react";
import ReactDOM from "react-dom/client";
// 导入仓库
import store from "./store";
import { Provider } from "react-redux";
// 导入项目的根组件
import App from "./App";
// 把App根组件渲染到id为root的dom节点上
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>
);
在react组件中使用store数据
useSelector---把store中的数据映射到组件中
App.vue
// 项目的根组件
import { useSelector } from "react-redux";
function App() {
const {count} = useSelector(state => state.counter)
return <div className="App">
<h1>this is title</h1>
{count}
</div>;
}
export default App;
修改store数据
useDispatch---生成提交action对象的dispatch函数
App.vue
// 项目的根组件
import { useEffect } from "react";
import { useSelector, useDispatch } from "react-redux";
// 导入创建action对象的方法
import { decrement, inscrement, addToNum } from "./store/modules/countStore";
import { fetchChannelList } from "./store/modules/channelStore";
function App() {
const {count} = useSelector(state => state.counter)
const {channelList} = useSelector(state => state.channel)
// 得到dispatch函数
const dispatch = useDispatch()
useEffect(() => {
dispatch(fetchChannelList())
}, [dispatch])
return <div className="App">
<button onClick={() => dispatch(decrement())}>-</button>
{count}
<button onClick={() => dispatch(inscrement())}>+</button>
<button onClick={() => dispatch(addToNum(10))}>add to 10</button>
<button onClick={() => dispatch(addToNum(20))}>add to 20</button>
<ul>
{channelList.map(item => <li key="item.id">{item.name}</li>)}
</ul>
</div>;
}
export default App;