首页 > 其他分享 >React — Redux详解

React — Redux详解

时间:2024-03-07 17:34:08浏览次数:21  
标签:const reducer dispatch React state 详解 action Redux store

Redux 是一个用于 JavaScript 应用程序的状态管理库。它可以帮助您管理应用程序中的状态,并确保状态的一致性和可预测性。

Redux 主要用于处理大型应用程序中的复杂状态逻辑,例如跨组件共享状态、处理异步数据流等。

Redux 的核心概念包括:

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

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

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

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

  5. 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)目录结构设计

2.使用方式

(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对象

3.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
         //参数会被传递到action对象的payload属性上
        } //在reducer的同步修改方法中添加action对象参数
    }//修改状态的方法 同步方法 支持直接修改
})

//解构出来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的时候传递参数

4.异步操作

(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])

 

标签:const,reducer,dispatch,React,state,详解,action,Redux,store
From: https://www.cnblogs.com/qinlinkun/p/18059389

相关文章

  • 常见中小型企业组网架构详解
    “ 中小型企业内网网络架构是怎么组成的,分几层结构,vlan怎样划分,常用到的动态路由协议,静态路由协议,基本上所有三层二层技术全部会用得到!”网络拓扑这里用Cisco的packettracer教学工具进行搭建演示。整体网络拓扑如下所示。应用到的技术有:OSPF、VLAN、VTP、Channel、HSRP、SVI、......
  • 多线程系列(十五) -常用并发工具类详解
    一、摘要在前几篇文章中,我们讲到了线程、线程池、BlockingQueue等核心组件,其实JDK给开发者还提供了比synchronized更加高级的线程同步组件,比如CountDownLatch、CyclicBarrier、Semaphore、Exchanger等并发工具类。下面我们一起来了解一下这些常用的并发工具类!二、常用并发......
  • 详解Python魔法函数,__init__,__str__,__del__
    1、简介Python作为一门灵活而强大的编程语言,提供了许多特殊的方法,被称为魔法函数(Magicmethods)。这些魔法函数以双下划线开头和结尾,能够让我们自定义类的行为,使得Python更加灵活和易用。本文将详细介绍Python中的魔法函数,帮助读者理解其作用和用法。1.1、什么是魔法函数?魔法函......
  • CMD命令大全详解
    1、gpedit.msc-----组策略。2.、sndrec32-------录音机。3、Nslookup-------IP地址侦测器,是一个监测网络中DNS服务器是否能正确实现域名解析的命令行工具。它在WindowsNT/2000/XP中均可使用,但在Windows98中却没有集成这一个工具。【cmd命令大全】一、CMD命令4、......
  • nginx rewrite参数详解
    Nginx的rewrite指令用于重写URL,它有几个参数,这些参数定义了如何匹配和重写请求的URL。以下是rewrite指令的常见参数及其说明:Regex:这是一个正则表达式,用于匹配请求的URI。Nginx将使用这个正则表达式来查找与请求URI相匹配的模式。Replacement:这是重写后的URI,可以包含正则表达式......
  • Unity3D 渲染队列 ZTest与ZWrite详解
    在Unity3D中,渲染队列(RenderingQueue)是一个非常重要的概念,它决定了游戏中各个物体的渲染顺序和优先级。而在渲染队列中,ZTest和ZWrite又是两个关键的参数,它们决定了物体在渲染的过程中如何处理深度测试和深度写入。本文将详细介绍Unity3D中的渲染队列、ZTest和ZWrite的概念,并给出相......
  • Unity3D 立方体纹理与自制天空盒详解
    在Unity3D中,立方体纹理和自制天空盒是常见的技术,它们可以帮助开发者创建出更加真实和引人入胜的游戏场景。本文将详细介绍Unity3D中立方体纹理和自制天空盒的实现方法,希望能帮助读者更好地理解和运用这些技术。对啦!这里有个游戏开发交流小组里面聚集了一帮热爱学习游戏的零基础小......
  • Unity3D 多人战场Animation优化详解
    在多人战场游戏中,动画的优化是非常重要的,因为动画是游戏中的核心元素之一,直接影响玩家的游戏体验。对啦!这里有个游戏开发交流小组里面聚集了一帮热爱学习游戏的零基础小白,也有一些正在从事游戏开发的技术大佬,欢迎你来交流学习。在本文中,我们将详细介绍如何在Unity3D中优化多人战......
  • React jsx 语法解析 & 转换原理
    jsx介绍jsx是一种JavaScript的语法扩展(eXtension),也在很多地方称之为JavaScriptXML,因为看起就是一段XML语法,用于描述UI界面,并且可以和JavaScript代码结合使用。比起vue中的模板语法,更加灵活,且不需要学习模板语法中的特定标签,比如:v-if、v-for、v-bind等,而是直接使用JavaScript语......
  • React Hooks 钩子特性及应用场景
    Hooks是React16.8的新增特性。它可以让你在不编写class组件的情况下使用state以及其他的React特性。ReactHooks表现形式是以use开头的函数被称为Hook。useState是React提供的一个内置Hook。你可以在ReactAPI参考中找到其他内置的Hook。你也可以通过组合......