前端学习--React(3)

一、Redux

集中状态管理工具,不需要react即可使用,每个store的数据都是独立于组件之外的

vue小链接:vuex/pinia

基本使用

Redux将数据修改流程分成三个概念,state、action和reducer

state - 一个对象 存放我们管理的数据状态

action - 一个对象 描述你如何修改数据

reducer - 一个函数 根据action的描述生成新的state

<button id="decrement">-</button>
<span id="count">0</span>
<button id="increment">+</button><script src="https://unpkg.com/redux@latest/dist/redux.min.js"></script><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. 使用reducer函数生成store实例const store = Redux.createStore(reducer)// 3. 通过store实例的subscribe订阅数据变化// 回调函数可以在每次state发生变化的时候自动执行store.subscribe(() => {console.log('state变化了', store.getState())document.getElementById('count').innerText = store.getState().count})// 4. 通过store实例的dispatch函数提交action更改状态 const inBtn = document.getElementById('increment')inBtn.addEventListener('click', () => {// 增store.dispatch({type: 'INCREMENT'})})const dBtn = document.getElementById('decrement')dBtn.addEventListener('click', () => {// 减store.dispatch({type: 'DECREMENT'})})// 5. 通过store实例的getState方法获取最新状态更新到视图中</script>

react中使用redux

相关工具

Redux Toolkit 简化redux书写逻辑

react-redux 链接Redux和React的中间件

npm i @reduxjs/toolkit react-redux

 安装成功

目录创建

创建src/store,modules存放子模块

counterStore.js

//1 导入并创建store
import {createSlice} from "@reduxjs/toolkit"const counterStore = createSlice({name:'counter',// 初始状态initialState:{count:0},// 更新状态的方法reducers:{inscrement(state){state.count++},descrement(state){state.count --}}
})const {inscrement, descrement} = counterStore.actions
const reducer = counterStore.reducerexport{inscrement,descrement
}export default reducer

store/index.js

集成store/modules中所有子模块

import { configureStore } from "@reduxjs/toolkit";
import counterReducer from "./modules/counterStore"// 将子模块中的所有store合成一个根store方便访问
const store = configureStore({reducer:{counter:counterReducer,}
})export default store

src/index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import store from "./store"
import { Provider } from 'react-redux';const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(// 通过react-redux提供的Provider 给组件注入store 使得redux定义的store能够被react组件使用<Provider store={store}><App /></Provider>
);

App.js

useDispatch() 通过这个来派发reducer修改状态

import { useSelector, useDispatch } from "react-redux";
import {inscrement, descrement} from "./store/modules/counterStore"
function App() {const { count } = useSelector(state => state.counter)const dispatch = useDispatch()return (<div className="App"><button onClick={() => dispatch(inscrement())}>+</button>{count}<button onClick={() => dispatch(descrement())}>-</button></div>);
}export default App;

然后就完成了:

进阶版-提交action时传参

counterStore.js

增加了一个addToNum函数

//1 导入并创建store
import {createSlice} from "@reduxjs/toolkit"const counterStore = createSlice({name:'counter',// 初始状态initialState:{count:0},// 更新状态的方法reducers:{inscrement(state){state.count++},descrement(state){state.count --},addToNum(state, action){// dispatch调用该方法时传入的参数就存放在action.payloadstate.count += action.payload}}
})const {inscrement, descrement, addToNum} = counterStore.actions
const reducer = counterStore.reducerexport{inscrement,descrement,addToNum
}export default reducer

 App.js

增加了两个值,传入不同参数

import { useSelector, useDispatch } from "react-redux";
import {inscrement, descrement, addToNum} from "./store/modules/counterStore"
function App() {const { count } = useSelector(state => state.counter)const dispatch = useDispatch()return (<div className="App"><button onClick={() => dispatch(inscrement())}>+</button>{count}<button onClick={() => dispatch(descrement())}>-</button><button onClick={() => dispatch(addToNum(10))}>+ 10</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:{getChannels(state, action){state.channelList = action.payload}}
})const {getChannels} = channelStore.actions//单独写一个异步action的函数 异步操作处理完毕后再调用同步action修改状态
const getChannelList = () => {return async(dispatch) => {const res = await axios.get('http://geek.itheima.net/v1_0/channels')dispatch(getChannels(res.data.data.channels))}
}export {getChannelList}const reducer = channelStore.reducer
export default reducer

 App.js

import { useSelector, useDispatch } from "react-redux";
import {inscrement, descrement, addToNum} from "./store/modules/counterStore"
import {getChannelList} from "./store/modules/channelStore"
import {useEffect} from 'react'
function App() {const { count } = useSelector(state => state.counter)const { channelList } = useSelector(state => state.channel)const dispatch = useDispatch()useEffect(()=> {dispatch(getChannelList())}, [dispatch])return (<div className="App"><button onClick={() => dispatch(inscrement())}>+</button>{count}<button onClick={() => dispatch(descrement())}>-</button><button onClick={() => dispatch(addToNum(10))}>+ 10</button><button onClick={() => dispatch(addToNum(-10))}>- 10</button><ul>{channelList.map(item => <li key={item.id}>{item.name}</li>)}</ul></div>);
}export default App;

调试工具redux devtools

直接在chorme商店里下载

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/211436.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

51单片机IO口的四种工作状态切换

51单片机IO口的四种工作状态切换 1.概述 这篇文章介绍单片机IO引脚的四种工作模式&#xff0c;每个模式都有各自的用武之地&#xff0c;后面在驱动外设硬件时会用它不同的模式。 2.IO口四种工作模式介绍 PnM1PnM0I/O口工作模式00准双向口&#xff1a;灌电流达20mA&#xff…

java--static的应用知识:单例设计模式

1.什么是设计模式(Design pattern) ①一个问题通常有n中解法&#xff0c;其中肯定有一种解法最优的&#xff0c;这个最优的解法被人总结出来了&#xff0c;称之为设计模式。 ②设计模式有20多种&#xff0c;对应20多种软件开发中会遇到的问题。 2.单例设计模式 确保一个类只…

2024东北师范大学计算机考研分析

24计算机考研|上岸指南 东北师范大学 信息科学与技术学院位于长春净月国家高新技术产业开发区&#xff0c;毗邻风光秀美的净月潭国家森林公园。 信息科学与技术学院由原“计算机科学与信息技术学院”和“信息与软件工程学院”于2017年根据学校事业发展需要整合形成。学院设有…

SPS简单对应分析

前言&#xff1a; 本专栏参考教材为《SPSS22.0从入门到精通》&#xff0c;由于软件版本原因&#xff0c;部分内容有所改变&#xff0c;为适应软件版本的变化&#xff0c;特此创作此专栏便于大家学习。本专栏使用软件为&#xff1a;SPSS25.0 本专栏所有的数据文件请点击此链接下…

ChatGPT有效开通方法*建议收藏*

ChatGPT Plus和API开通方法*建议收藏* 前期准备&#xff1a; 一个ChatGPT账户 一张虚拟卡 开通ChatGPT Plus会员&#xff0c;很多朋友担心虚拟卡订阅会封号&#xff0c;只要不勤换登陆IP不会使出现问题。而且目前大部分用户都是使用虚拟卡开通的会员 第一步&#xff1a;登…

【SpringCloud】什么是微服务?

一、单体架构 单体架构就是把所有业务模块编写在一个项目&#xff0c;最终打包成一个 war 包&#xff0c;进行部署 单体架构的优点&#xff1a; 部署简单&#xff1a;由于是完整的结构体&#xff0c;可以直接部署在一个服务器上即可 技术单一&#xff1a;项目不需要复杂的…

单词搜索黄金矿工

79. 单词搜索 中等 1.7K 相关企业 给定一个 m x n 二维字符网格 board 和一个字符串单词 word 。如果 word 存在于网格中&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 单词必须按照字母顺序&#xff0c;通过相邻的单元格内的字母构成&#xff0c;其中“相…

联合众筹模式系统源码:创新体验 支持队伍模式+支持转移 附带完整的搭建教程

众筹模式的日益普及&#xff0c;一种全新的联合众筹模式系统源码正在崭露头角。这款源码以创新体验为核心&#xff0c;支持队伍模式和支持转移功能&#xff0c;同时附带完整的搭建教程&#xff0c;为广大开发者带来了一场前所未有的便捷。 以下是部分代码示例&#xff1a; 系统…

boardmix AI思维导图,一键自动生成思维导图!

在日常学习和工作中&#xff0c;我们常常需要记忆和整理大量的知识点和思维结构。 此时&#xff0c;思维导图的存在就大大方便了我们的工作。与传统的文本笔记不同&#xff0c;思维导图可以结合文字、图像、颜色等多种元素&#xff0c;帮助我们更好地整理和分析知识的关系&…

竞赛选题 题目: 基于深度学习的疲劳驾驶检测 深度学习

文章目录 0 前言1 课题背景2 实现目标3 当前市面上疲劳驾驶检测的方法4 相关数据集5 基于头部姿态的驾驶疲劳检测5.1 如何确定疲劳状态5.2 算法步骤5.3 打瞌睡判断 6 基于CNN与SVM的疲劳检测方法6.1 网络结构6.2 疲劳图像分类训练6.3 训练结果 7 最后 0 前言 &#x1f525; 优…

浅析基于智能音视频技术的城市重要场馆智能监控系统设计

了解旭帆科技的朋友都知道&#xff0c;旭帆科技一直都乐于和大家分享各类场景的视频解决方案&#xff0c;今天小编就基于智能音视频技术的城市重要场馆智能监控系统设计和大家探讨一下。 基于智能音视频技术的城市重要场馆智能监控系统设计&#xff0c;主要包含以下要素&#x…

前端 计算机基础篇 ( 二 )

文章目录 websockt及原理ipv4和ipv6的区别线程和进程的区别cdn原理缓存所涉及的http状态码缓存的时候设置 no-store和no-cache和max-age0这几个有什么区别token一般存放在哪儿怎么设置强缓存和协商缓存强缓存&#xff1a;1. 使用 Cache-Control 头字段&#xff1a; 协商缓存&am…