今天学的不多喵()事情有点多,小忙
基本介绍
是React最常用的集中状态管理工具,类似于Vue的Pinia(Vuex),可以独立于框架运行。

使用步骤:
我们先脱离框架,使用纯redux实现计数器。
- 定义一个 reducer 函数 (根据当前想要做的修改返回一个新的状态)
- 使用 createStore 方法传入 reducer 函数 生成一个 store 实例对象
- 使用 store 实例的 subscribe 方法 订阅数据的变化 (数据一旦变化,可以得到通知)
- 使用 store 实例的 dispatch 方法提交 action 对象 触发数据变化 (告诉reducer你想怎么改数据)
- 使用 store 实例的 getState 方法 获取最新的状态数据更新到视图中
<button id="decrement">-</button>
<span id="count">0</span>
<button id="increment">+</button>
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.2.1/redux.min.js"></script>
<script>
/*1.定义reducer函数根据不同的action对象返回不同的state*/
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.生成实例*/
const store = Redux.createStore(reducer)
/*3.订阅数据变化,回调函数在每次state变化的时候自动执行*/
store.subscribe(()=>{
console.log('data changed')
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>
Redux 的单向数据流:
- View:用户点击了一个按钮(比如“购买”)。
- Dispatch Action :视图发出一个 Action。例如:
{ type: 'ADD_TO_CART', product: 'Book' }。 - Reducer (处理):Reducer 收到这个 Action,根据它执行逻辑(原来的购物车数量 +1)。
- Store (仓库):Reducer 返回的新状态被存入 Store(图中那个装着很多 state 的大框子)。
- View Update (更新视图):由于 Store 里的 State 变了,界面(View)会自动感知并重新渲染,显示购物车里有了 1 本书。
这样做你知道每一笔数据改变是谁引起的,如果数据错了,你只需要检查那个对应的 Reducer 逻辑,而不需要搜遍整个项目的代码。
环境准备
react中使用redux我们需要ReduxToolkit(RTK)和react-redux两个插件。
RTK是官方推荐的编写Redux逻辑的方式,是一个工具集。
react-redux是链接redux和组件的中间件。
npm install @reduxjs/toolkit react-redux
目录结构设计
创建Store目录,然后新建main.js,和modules文件夹,store的入口文件组合文件夹中的子模块并且导出,为一个store对象。
代码实现
我们再次实现计数器案例
counterStore.js
import {createSlice} from "@reduxjs/toolkit"
const counterStore = createSlice({
name: 'counter',
initialState:{
count:0
},
reducers:{
increment(state) {
state.count++
},
decrement(state){
state.count--
}
}
})
/*解构actionCreater函数 */
const {increment,decrement} = counterStore.actions
const reducer = counterStore.reducer
export{increment,decrement}
export default reducer
main.js
import { configureStore } from "@reduxjs/toolkit";
import counterReducer from "./modules/counterStore";
const store = configureStore({
reducer:{
counter:counterReducer
}
})
export default store
为react注入store,用内置的Provider组件注入到应用中链接正式建立。
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import App from './App.jsx'
import store from './store/main.js'
import { Provider } from "react-redux"
createRoot(document.getElementById('root')).render(
<StrictMode>
<Provider store={store}>
<App />
</Provider>
</StrictMode>,
)
使用钩子函数useSelector把store里面的数据映射到组件中
import { useSelector } from 'react-redux'
function App () {
// 使用 useSelector 从 store 中提取 count 状态
const { count } = useSelector(state => state.counter)
return (
<div className="App">
{count}
</div>
)
}
export default App
使用钩子函数useDispatch,修改store中的数据。
import { userDispatch, useSelector } from 'react-redux'
import {decrement,increment} from './store/modules/counterStore'
function App () {
// 使用 useSelector 从 store 中提取 count 状态
const { count } = useSelector(state => state.counter)
const dispatch = useDispatch()
return (
<div className="App">
<button onClick={() => dispatch(decrement())}>-</button>
<span>{count}</span>
<button onClick={() => dispatch(increment())}>+</button>
</div>
)
}
export default App
提交action传参
上面的单击按钮按一下增加1,但是我想要增加一个任意值呢?
import {createSlice} from "@reduxjs/toolkit"
const counterStore = createSlice({
name: 'counter',
initialState:{
count:0
},
reducers:{
increment(state) {
state.count++
},
decrement(state){
state.count--
},
addToNum(state,action) {
state.count = action.payload
}
}
})
/*解构actionCreater函数 */
const {increment,decrement,addToNum} = counterStore.actions
const reducer = counterStore.reducer
export{increment,decrement,addToNum}
export default reducer
我们增加一个reducer,这里需要传入action
import { userDispatch, useSelector } from 'react-redux'
import {decrement,increment,addToNum} from './store/modules/counterStore'
function App () {
// 使用 useSelector 从 store 中提取 count 状态
const { count } = useSelector(state => state.counter)
const dispatch = useDispatch()
return (
<div className="App">
<button onClick={() => dispatch(decrement())}>-</button>
<span>{count}</span>
<button onClick={() => dispatch(increment())}>+</button>
<button onClick={() => dispatch(addToNum(10))}>+10</button>
</div>
)
}
export default App
异步状态操作
样板代码
channelStore.js
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 }
export default channelStore.reducer
单独封装一个函数,内部 return 一个 async 函数,在里面 await 请求完后再 dispatch 同步方法,来实现异步逻辑
main.js
import { configureStore } from "@reduxjs/toolkit";
import counterReducer from "./modules/counterStore";
import channelReducer from "./modules/channelStore"
const store = configureStore({
reducer:{
counter:counterReducer,
channel: channelReducer
}
})
export default store
App.jsx
import { useEffect } from 'react'
import { useSelector, useDispatch } from 'react-redux'
import { fetchChannelList } from './store/modules/channelStore'
function App() {
const dispatch = useDispatch()
const { channelList } = useSelector(state => state.channel)
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调试——devtools

下一下浏览器插件,然后打开开发者工具找到这个图片就能打开这个插件

//具体使用这里就不多描述了喵。








