React笔记(三)
2024 年 5 月 3 日 星期五(已编辑)
/
6
摘要
Rudex是React中常用的集中状态管理工具,类似于Vue中的Vuex,在React中可以独立运行。Redux Toolkit是官方推荐的编写Redux逻辑的方式,包含一套工具集,简化书写方式。react-redux是连接Redux和React组件的中间件。通过定义reducer函数和使用createStore方法生成store实例对象,可以订阅数据的变化并触发数据变化。使用useDispatch和useSelector钩子函数来获取store数据并修改,实现组件获取数据并修改的功能。同时还可以进行异步操作,通过封装异步函数来异步修改状态。
这篇文章上次修改于 2024 年 5 月 7 日 星期二,可能部分内容已经不适用,如有疑问可询问作者。
阅读此文章之前,你可能需要首先阅读以下的文章才能更好的理解上下文。
1.Rudex
Rudex是React中最常用的集中状态管理工具,类似于Vue中的Vuex,可以独立于框架运行
//1.定义一个reducer函数(根据当前想要做的修改返回一个新的状态)
function reducer (state = {count: 0 }){
//数据不可变,基于原始状态生成新的状态
if(action.type === 'INCREMENT'){
return {cout:state.count + 1}
}
if(action.type === 'DECREMENT'){
return {cout:state.count - 1}
}
return state
};
//2.使用createStore方法传入reduce函数生成一个store实例对象
const store = Rudex.createStore(reducer)
//3.使用store实例的subscribe方法订阅数据的变化(数据一旦变化,可以得到通知)
store.subscribe(()=>{
console.log('state已改变')
})
//4.使用store实例的dispatch方法提交action对象触发数据变化(告诉reducer想怎么该数据)
store.dispatch({
type: 'INCREMENT'
})
//5.使用store实例的getState方法获取最新的状态数据更新到视图中
store.getState()
2.React--Rudex
1.Redux Toolkit(RTK) - 官方推荐编写Redux逻辑的方式,是一套工具的集合,简化书写方式
2.react-redux - 用来链接Redux和React组件的中间件
npm i @reduxjs/toolkit react-redux
2.1 生成store
import {createSlice} from "@reduxjs/toolkit";
const counterStore = createSlice({
name: 'counter',
//初始化数据
initialState: {
count: 0
},
//修改数据的同步方法
reducers: {
increment (state){
if(state.count<=8){
state.count++
}
},
decrement (state) {
if(state.count>=1){
state.count--
}
},
addToSum (state,action) {
state.count = action.payload //传值
}
}
})
//解析出创建action对象的构造方法 (actionCreater)
const {increment,decrement,addToSum} = counterStore.actions
//获取reducer函数
const reducer = counterStore.reducer
//导出创建action对象的函数和reducer函数
export { increment, decrement ,addToSum}
export default reducer
//index.js -- 集中管理
import {configureStore} from "@reduxjs/toolkit";
import counterReducer from "./modules/counterStore";
//创建根store组合子模块
const store = configureStore({
reducer: {
counter: counterReducer
}
})
export default store
2.2 全局导入 -- 将store与组件绑定
/* src/index.js */
import {Provider} from "react-redux";
import store from "./store/index";
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>
);
2.3 组件获取数据并修改
import {useDispatch, useSelector} from "react-redux";
import {decrement, increment} from "./store/modules/counterStore";
function CounterButton() {
const { count } = useSelector(state => state.counter)//useSelector钩子函数用于获取store数据
const dispatch = useDispatch() //useDispatch钩子函数用于获取dispatch方法
return (
<div className="container">
<button onClick={()=>dispatch(decrement())}>-</button> {//提交action对象}
<span>{count}</span>
<button onClick={()=>dispatch(increment())}>+</button>
</div>
)
}
异步操作
//1.创建store的写法相同,配置好同步修改状态的方法
const channelStore = createSlice({
name: 'channel',
initialState: {
channellist: []
},
reducer: {
setChannels(state,action) {
state.channelist = action.payload
}
}
})
//2.单独封装一个函数,在函数内部return一个新函数
const { setChannels } = channelStore.actions
const reducer = channelStore.reducer
const url = '...'
const fetchChannelList = () => {
return async (dispatch) => {
const res = await axios.get(url)
dispatch(setChannels(res.data.data.channels))
}
}
export { fetchChannelList }
//3.组件中dispatch写法不变
const dispatch = useDispatch()
useEffect(() => {
dispatch(fetchChannlList())
},[dispatch])