问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

React — Redux详解

创作时间:
作者:
@小白创作中心

React — Redux详解

引用
1
来源
1.
https://www.cnblogs.com/qinlinkun/p/18059389

Redux 是一个用于 JavaScript 应用程序的状态管理库。它可以帮助您管理应用程序中的状态,并确保状态的一致性和可预测性。Redux 主要用于处理大型应用程序中的复杂状态逻辑,例如跨组件共享状态、处理异步数据流等。

Redux 核心概念

  • Store(存储):Redux 应用程序的状态(state)被统一存储在一个称为 Store 的对象中。这个状态是只读的,唯一改变状态的方式是通过分发(dispatching)一个 action。

  • Action(动作):Action 是描述发生了什么事情的纯 JavaScript 对象。它必须包含一个 type 属性来指明动作的类型,通常还会包含一些与动作相关的数据。

  • Reducer(归纳器):Reducer 是一个纯函数,接收先前的状态和一个 action,并返回新的状态。Reducer 负责根据 action 更新应用程序的状态。

  • Dispatch(分发):使用 store.dispatch(action) 方法来分发一个 action,这是唯一能改变状态的方法。

  • Selector(选择器):选择器用于从 Store 中提取部分状态数据,以便在应用程序的组件中使用。

Redux 的工作流程是:当应用程序中的某个地方发生了变化,比如用户交互或者网络请求返回数据,就会创建一个对应的 action 并被分发到 store 中。然后,相应的 reducer 会根据 action 更新 store 中的状态。最后,React 组件可以订阅 store 中的状态,并根据状态的变化来更新界面。

通过这种方式,Redux 提供了一种可预测且一致的状态管理机制,使得应用程序的状态变化变得容易追踪和调试。这使得 Redux 成为处理大型复杂应用程序状态的理想选择。

CDN 引入 JS 使用 Redux

  1. 定义一个 reducer 函数(根据当前想要做的修改返回一个新的状态)
  2. 使用 createStore 方法传入 reducer 函数生成一个 store 实例对象
  3. 使用 store 实例的 subscribe 订阅数据的变化(数据一旦变化,可以得到通知)
  4. 使用 store 实例的 dispatch 方法提交 action 对象触发数据变化(告诉 reducer 你想怎么改数据)(修改数据的唯一方式)
  5. 使用 store 实例的 getState 方法获取最新的状态数据更新到视图中
<script src="https://cdnjs.cloudflare.com/ajax/libs/redux/4.1.1/redux.min.js"></script>
<div class="sum">
 <button id="reduce">
 -
 </button>
 <span id="num">
 0
 </span>
 <button id="add">
 +
 </button>
 </div>
<script>
 //1.定义reducer函数 : 根据不用的action函数,返回不同的state
 //state:管理数据的初始状态
 //action:对象 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.使用createStore方法传入reducer函数 生成一个store实例对象
 const store = Redux.createStore(reducer)
 //3.通过store实例的subscribe订阅数据变化
 store.subscribe(()=>{
 console.log('state变化了',store.getState())
 document.getElementById('num').innerText=store.getState().count
 })
 //4.使用store实例的dispatch方法提交action对象触发数据变化
 const inBtn = document.getElementById('add')
 const dBtn = document.getElementById('reduce')
 inBtn.addEventListener('click',()=>{
 store.dispatch({
 type:'INCREMENT'
 })
 })
 dBtn.addEventListener('click',()=>{
 store.dispatch({
 type:'DECREMENT'
 })
 })
</script>

creatReactApp(框架)使用 Redux

  1. 创建环境
npm i @reduxjs/toolkit react-redux

(1)Redux Toolkit(RTK) 官方推荐编写Redux逻辑的方式,是一套工具的集合集,简化书写方式
(2)react-redux 用来链接Redux和React组件的中间件
(3)目录结构设计

  1. 使用方式

(1)配置子模块(子store)

import {createSlice} from "@reduxjs/toolkit"
//createSlice 创建store的方法
const countStore = createSlice({
 name : 'counter', //给模块一个名字
 initialState:{
 count : 0
 }, //初始化state
 reducers :{
 add(state){
 state.count++
 },
 reduce(state){
 state.count--
 },
 }//修改状态的方法 同步方法 支持直接修改
})
//解构出来actionCreater函数==》解构出来的方法叫做actionCreater (也就是说这些方法是生成action对象的)
const {add,reduce} = countStore.actions
//获取reducer函数
const reducer = countStore.reducer
//导出创建action对象的函数和reducer函数
export {add,reduce,addNum}
export default reducer

(2)index.js入口文件配置根store并组合子store

import {configureStore} from "@reduxjs/toolkit" //组合子模块的方法
import countReducer from './modules/counterStore' //导入子模块
//配置
const store=configureStore({
 reducer:{
 counter : countReducer,
 }
})
//导出
export default store

(3)在react中注入store

import store from './store/index'
import {Provider} from 'react-redux' 
//react-redux负责把Redux和React连接起来,内置Provider组件通过store参数把创建好的store实例注入到应用中,链接正式建立
//把App根组件渲染到id为root的dom节点
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
 <Provider store={store}>
 <App />
 </Provider>
);

(4)使用store中的数据 修改store中的数据

import { useSelector,useDispatch } from 'react-redux';
//在React组件中使用store的数据,需要用到一个钩子函数useSelector,他的作用是把store中的数据映射到组件中
import {add,reduce} from './store/modules/counterStore'
//导入actionCreater  
function App(){
 const {count} = useSelector(state=>state.counter)
 const dispatch = useDispatch()
//React组件中修改store中的数据需要借助另一个hook函数 useDispatch ,他的作用是生成提交action对象的dispatch函数
return <div>
<div>
 <button onClick={()=>{
 dispatch(reduce())
 }}>-</button>
 <span>{count}</span>
 <button onClick={()=>{
 dispatch(add())
 }}>+</button>
 </div>
</div>
}

(5)总结

组件中使用 useSelector (hook函数)获取store中的对象
组件中使用 useDispatch (hook函数)获取dispatch方法
执行store模块中导出的actionCreater方法就能得到要提交的action对象

  1. action传参

(1)在reducer的同步修改方法中添加action对象参数

const countStore = createSlice({
 name : 'counter', //给模块一个名字
 initialState:{
 count : 0
 }, //初始化state
 reducers :{
 add(state){
 state.count++
 },
 reduce(state){
 state.count--
 },
 addNum(state,action){
 state.count= state.count+action.payload
 }
 }
})
//解构出来actionCreater函数==》解构出来的方法叫做actionCreater (也就是说这些方法是生成action对象的)
const {add,reduce,addNum} = countStore.actions
//获取reducer函数
const reducer = countStore.reducer
export {add,reduce,addNum}
export default reducer

(2)调用actionCreater的时候传递参数,参数会被传递到action对象的payload属性上

<div>
 <button onClick={()=>{
 dispatch(reduce())
 }}>-</button>
 <span>{count}</span>
 <button onClick={()=>{
 dispatch(add())
 }}>+</button>
 <button onClick={()=>{
 dispatch(addNum(10))
 }}>
 +10
 </button>
 <button onClick={()=>{
 dispatch(addNum(20))
 }}>
 +20
 </button>
 </div>
//调用actionCreater的时候传递参数
  1. 异步操作

(1)配置store

(2)同步修改

const channelStore=createSlice({
    name : 'channel', //定义子store的名字
    initialState :{
        channelList : [] //初始化数据的状态
    },
    reducers:{  
 setList(state,action){
 state.channelList = action.payload
 }
 }
})

(3)异步修改

//异步请求  
const {setList} = channelStore.actions  
const channelAsync=()=>{
 return async (dispatch)=>{
 const res = await axios.get('。。。') //封装异步请求获取数据
 dispatch(setList(res.data.data.channels)) //调用同步actionCreater传入异步数据生成的一个action对象,并使用dispatch提交
 }
}

(4)使用store的数据

(5)diapatch提交action对象更新store

import {channelAsync} from './store/modules/channelStore'
const {channelList} = useSelector(state=>state.channel)
const dispatch = useDispatch()
 //React组件中修改store中的数据需要借助另一个hook函数 useDispatch ,他的作用是生成提交action对象的dispatch函数
 useEffect(()=>{
 dispatch(channelAsync()//异步操作生成的就不是一个action对象了 是一个action函数)
 },[dispatch])

本文原文来自cnblogs

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号