Redux是什么?
Redux是React最常见的集中状态管理工具,类似于Vue中的Pinia (Vuex) ,可以独立于框架运行
作用:通过集中管理的方式管理应用的状态
使用步骤:
- 定义一个reducer函数(根据当前想要做的修改返回一个新的状态)
- 使用createStore方法传入reducer函数生成一个store实例对象
- 使用store实例的subscribe方法订阅数据的变化(数据一旦变化,可以得到通知)
- 使用store实例的dispatch方法提交action对象触发数据变化(告诉reducer你想怎么更改数据)
- 使用store实例的getState方法获取最新的状态数据更新到视图中
react中使用redux
在react中使用redux,官方要求安装两个其他插件——Redux Toolkit 和 react-redux
Redux Toolkit (RTK)
官方推荐编写Redux逻辑的方式,是一套工具的集合集,简化书写方式
- 简化store的配置方式
- 内置immer支持可变式状态修改
- 内置thunk更好的异步创建
react-redux
react-redux是用来链接redux和react组件的中间件
安装redux配套工具
npm install @reduxjs/toolkit react-redux
store目录结构
index.js
import { configureStore } from "@reduxjs/toolkit";
import counterReducer from './modules/counterStore'
//创建根store组合子模块
const store = configureStore({
reducer: {
//子模块
counter: counterReducer
}
})
export default store
子模块 modules目录下的模块 使用需要引入到index
import { createSlice } from '@reduxjs/toolkit'
const counterStore = createSlice({
name: 'counter',
// 初始化state
initialState: {
count: 0,
},
// 修改状态的方法,支持直接修改
reducers: {
plus(state) {
state.count++
},
minus(state) {
state.count--
}
}
})
//结构actionCreater函数
const { plus, minus } = counterStore.actions
//获取reducer
const counterReducer = counterStore.reducer
// 按需导出
export { plus, minus }
// 默认导出
export default counterReducer
项目的入口文件 注入 根目录下的index.js文件
react-redux复制把redux和react链接起来,内置Provider组件通过store参数把创建好的store实例注入到应用中,链接正式建立
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
//引入store
import store from './store/index'
import { Provider } from 'react-redux'
//使用provider包裹项目根组件
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<Provider store={store}>
<App />
</Provider>
</React.StrictMode>
);
组件中使用 useSelector
在react组件中使用store中的数据,需要用到一个钩子函数-useSelector,它的作用是把store中的数据映射到组件中
注意: const {count} = useSelector(state=>state.counter) counter需要于store下index.js中reducer里声明的对应
import { useSelector } from 'react-redux' //引入
const {count} = useSelector(state=>state.counter)
直接使用count即可
组件中修改store中的数据 useDispatch
在react组件中修改store中的数据,需要借助另一个hook函数-useDispatch,它的作用是生成提交action对象的dispatch函数
import { useSelector,useDispatch } from 'react-redux'
//导入声明的修改状态的方法
import { add,minus } from './store/modules/counterStore'
function App() {
const {count} = useSelector(state=>state.counter)
//声明useDispatch
const dispatch = useDispatch()
return (
<div className="App">
<button onClick={()=>dispatch(minus())}>-</button>
<span>{ count }</span>
<button onClick={()=>dispatch(add())}>+</button>
</div>
);
}
export default App;
传递参数 提交action传参
在reducers的同步方法中添加action对象参数,在调用actionCreater的时候传递参数,参数会被传递到action对象的payload属性上
import { createSlice } from '@reduxjs/toolkit'
const counterStore = createSlice({
name: 'counter',
// 初始化state
initialState: {
count: 0,
},
// 修改状态的方法,支持直接修改
reducers: {
add(state,action) {
console.log(action.payload); //接收到传递的参数
state.count++
},
minus(state) {
state.count--
}
}
})
//结构actionCreater函数
const { add, minus } = counterStore.actions
//获取reducer
const counterReducer = counterStore.reducer
// 按需导出
export { add, minus }
// 默认导出
export default counterReducer
//传递参数
<button onClick={()=>dispatch(add({num:10,add:20}))}>+</button>
异步操作 异步修改
//asyncStore 模块
import { createSlice } from '@reduxjs/toolkit'
import axios from 'axios'
const asyncStore = createSlice({
name: 'async',
// 初始化state
initialState: {
list:[{name:'11'},{name:'222'}]
},
// 修改状态的方法,支持直接修改
reducers: {
setList(state,action) {
console.log(action.payload);
state.list = action.payload
},
}
})
//结构actionCreater函数
const { setList } = asyncStore.actions
//获取reducer
const asyncReducer = asyncStore.reducer
//封装异步请求函数
const getlist = ()=>{
return async(dispatch)=>{
let res = await axios.get('http://geek.itheima.net/v1_0/channels')
console.log(res);
//使用dispatch提交
dispatch(setList(res.data.data.channels))
}
}
// 按需导出 导出异步请求函数
export { getlist }
// 默认导出
export default asyncReducer
//组件使用
import { useSelector,useDispatch } from 'react-redux'
//导入声明的修改状态的方法
import { getlist } from './store/modules/asyncStore'
function App() {
const { list } = useSelector(state=>state.async)
//声明useDispatch
const dispatch = useDispatch()
return (
<div className="App">
<ul>
{list.map(item=><li key={item.name}>{item.name}</li>)}
</ul>
<button onClick={()=>dispatch(getlist())}>调接口</button>
</div>
);
}
export default App;
react redux调试工具 dexvtools
Redux DevTools 可以去插件小屋进行下载