一、redux
redux 作为一个优秀的状态管理工具,react-reudx也值得我们学习
1、实现一个counter
推荐的文件结构如下:
store
modules
xxxStore.js
index.js
1.1、首先实现store module/counterStore.js
值得注意的是需要安装 @reduxjs/toolkit
react-redux
import { createSlice } from "@reduxjs/toolkit";
const countStore = createSlice({
name: 'counter', //name 只是为了在调试中看到具体是哪个store
initialState: {
count: 0
},
reducers: {
increment(state) {
state.count++
},
decrement(state) {
state.count--
},
addToNum(state, action) {
state.count += action.payload
}
}
})
// 解构出来actionCreate 函数
const { increment, decrement, addToNum } = countStore.actions
// 获取reducer
const counterReducer = countStore.reducer
export { increment, decrement, addToNum }
export default counterReducer
值得注意的是 reducers 里面有三个方法 ,其中第三个addToNum 就是我们需要通过action 传参,那么 可以通过action.payload
获取到传递参数。
1.2、统一导出 index,js
import { configureStore } from "@reduxjs/toolkit";
import counterRudecer from './modules/counterStore'
const store = configureStore({
reducer: {
counter: counterRudecer,
}
})
export default store
1.3、全局注入
import React from 'react'
import ReactDOM from 'react-dom/client'
// import App from './App.jsx'
import Counter from './Components/Counter'
import { Provider } from 'react-redux' //通过 react-redux 提供的Provider 包裹需要使用组件
import store from './store'
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
<Provider store={store}>
<Counter />
</Provider>
</React.StrictMode>,
)
1.4、使用 Counter.js
import { useDispatch, useSelector } from "react-redux"
import { increment, decrement, addToNum } from "../../store/modules/counterStore"
import { useEffect } from "react"
const Counter = () => {
const { count } = useSelector(state => state.counter)
const { channelList } = useSelector(state => state.channel)
const dispatch = useDispatch()
const handleAdd = () => {
dispatch(increment())
}
const handleDepre = () => {
dispatch(decrement())
}
const handleAddTen = () => {
dispatch(addToNum(10))
}
return (
<div>
<button onClick={handleAdd}>+</button>
<h2>{count}</h2>
<button onClick={handleDepre}>-</button>
<button onClick={handleAddTen}>add 10</button>
</div>
)
}
export default Counter;
2、实现一个异步redux
2.1、实现store
import { createSlice } from "@reduxjs/toolkit";
import axios from "axios";
const channelStore = createSlice({
name: 'channel',
initialState: {
channelList: []
},
reducers: {
setChannelList(state, action) {
state.channelList = action.payload
}
}
})
const { setChannelList } = channelStore.actions
// 值得注意的是需要在这里通过dispatch 来进行设置
const fetchChannelList = () => {
return async (dispatch) => {
const res = await axios.get('http://geek.itheima.net/v1_0/channels')
dispatch(setChannelList(res.data.data.channels))
}
}
export { fetchChannelList }
const reducer = channelStore.reducer
export default reducer
2.2、统一导出 index,js
import { configureStore } from "@reduxjs/toolkit";
import counterRudecer from './modules/counterStore'
import channelReducer from './modules/channelStore'
const store = configureStore({
reducer: {
counter: counterRudecer,
channel: channelReducer
}
})
export default store
2.3、使用
import { useDispatch, useSelector } from "react-redux"
import { fetchChannelList } from '../../store/modules/channelStore'
import { useEffect } from "react"
const Counter = () => {
const { channelList } = useSelector(state => state.channel)
const dispatch = useDispatch()
useEffect(() => {
dispatch(fetchChannelList())
}, [])
return (
<div>
<ul>
{channelList.map(item => <li>{item.name}</li>)}
</ul>
</div>
)
}
export default Counter;