React学习笔记(三)
1、useSelecter
2、useDispatch
3、执行store模块中导出的action Creater方法
一、Redux是什么?
Redux是React
最常用的集中状态管理工具,类似Vue中的Pinia(Vuex),可以独立于框架运行。
作用:通过集中管理的方式管理应用的状态。
二、使用步骤
1.redux快速体验
代码如下(示例):
<button id="decrement">-</button>
<span id="count">0</span>
<button id="increment">+</button>
<!-- <script src="https://unpkg.com/redux@latest/dist/redux.min.js"></script> -->
<script src="http://cdn.bootcss.com/redux/3.6.0/redux.js"></script>
<script>
// 1、定义reducer函数:根据不同的action对象 返回不同的state
// action: 管理数据的初始状态 state: 对象type标记当前想要做什么样的修改
function reducer(state = { count: 0 }, action) {
if (action.type === "INCREMENT") {
// 返回新状态:数据不可变,基于原始状态生产一个新的状态
return { count: state.count + 1 };
}
if (action.type === "DECREMENT") {
return { count: state.count - 1 };
}
return state;
}
// 2、使用reducer函数生成store实例
const store = Redux.createStore(reducer);
// 3、通过store实例的subscribe订阅数据变化
store.subscribe(() => {
console.log("state变化了", store.getState());
document.getElementById("count").innerText = store.getState().count;
});
const inBtn = document.getElementById("increment");
inBtn.addEventListener("click", () => {
store.dispatch({
type: "INCREMENT",
});
});
const dBtn = document.getElementById("decrement");
dBtn.addEventListener("click", () => {
store.dispatch({
type: "DECREMENT",
});
});
</script>
<style>
body {
font-size: 34px;
}
#count {
color: red;
margin: 0 10px;
}
button {
width: 100px;
height: auto;
font-size: 40px;
}
</style>
2.基于@reduxjs/toolkit使用react-redux
工具包:Redux Toolkit (RTK)
中间件: react-redux
- 添加 Redux Toolkit 和 React-Redux 依赖包到你的项目中:npm i @reduxjs/toolkit react-redux
npm i @reduxjs/toolkit react-redux
- 创建store文件夹:modules存储子store模块,index.js组合modules中所有子模块,并导出store
- index.js
import { configureStore } from "@reduxjs/toolkit";
import counterReducer from "./modules/counterStore";
export default configureStore({
reducer: {
counter: counterReducer,
},
});
- counterStore.js
import { createSlice } from "@reduxjs/toolkit";
export const counterSlice = createSlice({
name: "counter",
initialState: {
value: 0,
},
reducers: {
increment: (state) => {
// Redux Toolkit 允许我们在 reducers 写 "可变" 逻辑。它
// 并不是真正的改变状态值,因为它使用了 Immer 库
// 可以检测到“草稿状态“ 的变化并且基于这些变化生产全新的
// 不可变的状态
state.value += 1;
},
decrement: (state) => {
state.value -= 1;
},
//payload接收参数
incrementByAmount: (state, action) => {
state.value += action.payload;
},
},
});
// 每个 case reducer 函数会生成对应的 Action creators
export const { increment, decrement, incrementByAmount } = counterSlice.actions;
export default counterSlice.reducer;
- 创建 store 后,便可以在 React 组件中使用它。通过 React-Redux 的 将 包裹起来,并将 store 作为 prop 传入。
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import store from "./store";
// 中间件 传递redux store
import { Provider } from "react-redux";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<Provider store={store}>
<App />
</Provider>
);
- 可以使用 React-Redux 钩子让 React 组件与 Redux store 交互。我们可以使用 useSelector 从 store 中读取数据,使用 useDispatch dispatch actions。
import React from "react";
import { useSelector, useDispatch } from "react-redux";
import { decrement, increment } from "./counterSlice";
import styles from "./Counter.module.css";
export function Counter() {
const count = useSelector((state) => state.counter.value);
const dispatch = useDispatch();
return (
<div>
<div>
<button
aria-label="Increment value"
onClick={() => dispatch(increment())}
>
Increment
</button>
<span>{count}</span>
<button
aria-label="Decrement value"
onClick={() => dispatch(decrement())}
>
Decrement
</button>
</div>
</div>
);
}
- 异步处理
1、channelStore.js
//从tookit中引入createSlice
import { createSlice } from '@reduxjs/toolkit'
// 引入axios
import axios from 'axios'
//定义数据
const listStore = createSlice({
name: 'list',
//初始化
initialState: {
list: [],
},
//修改同步方法
reducers: {
setList(state, action) {
state.list = action.payload
},
},
})
//解构出来reducers
const { setList } = listStore.actions
//异步请求方法
const fetchChannelList= () => {
return async (dispatch) => {
const res = await axios.get('接口地址')
dispatch(setList(res.data.data.channels))
}
}
//获取reducer
const reducer = listStore.reducer
//导出异步方法
export { fetchChannelList}
//默认导出reducer
export default reducer
2、index.js
import { configureStore } from '@reduxjs/toolkit'
//引入默认导出的
import counterReducer from './modules/counterStore'
import channelStore from './modules/channelStore'
//创建根store组合子模块
const store = configureStore({
reducer: {
counter: counterReducer,
channelList: channelStore,
},
})
//导出
export default store
3、页面中引入
//从react-redux中引入useSelector useDispatch
import { useSelector, useDispatch } from 'react-redux'
import { useEffect } from 'react'
//导入获取列表异步方法
import { fetchChannelList } from './store/modules/channelStore'
function App() {
const dispatch = useDispatch()
useEffect(() => {
dispatch(fetchChannelList())
}, [dispatch])
//解构
const { list } = useSelector((state) => state.channelList)
//得到dispatch函数
return (
<div className="App">
<ul>
{list.map((item) => (
<li key={item.id}>{item.name}</li>
))}
</ul>
</div>
)
}
export default App
3.redux-devtools 插件 安装和使用
参考地址:https://www.jianshu.com/p/029ab5ae37ba
总结
1、组件中使用哪个hook函数获取store中的数据?
2、组件中使用哪个hook函数获取dispatch方法?
3、如何得到要提交action对象?