网站建设优化建站/seo网络推广知识

网站建设优化建站,seo网络推广知识,网站可以同时做竞价和优化吗,做任务换流量的网站状态管理库,集中式存储状态,管理状态 ✅ redux //简单实现 redux源码 export function createStore(reducer) {// reducer由用户编写, 必须是一个函数,dispatch的时候,reducer要执行if (typeof reducer ! function) t…

状态管理库,集中式存储状态,管理状态

✅ redux

在这里插入图片描述

//简单实现 redux源码
export function createStore(reducer) {// reducer由用户编写, 必须是一个函数,dispatch的时候,reducer要执行if (typeof reducer !== 'function') throw new Error('reducer必须是一个函数')let state // 公共状态let listeners = [] //事件池// 1.获取公共状态  store.getState()const getState = () => {return state}// 2.组件更新方法 进入事件池const subscribe = listener => {if (typeof listener !== 'function') throw new Error('listener 必须是一个函数')// 去重,防止重复添加if (!listeners.includes(listener)) {// 让组件更新的方法进入事件池listeners.push(listener)}// 返回一个函数,用于从事件池中删除对应的方法 (取消订阅)return function unsubscribe() {// 找到事件池中的对应方法,并删除listeners = listeners.filter(l => l !== listener)}}// 3.派发任务通知 Reducer 执行const dispatch = action => {// 必须是对象if (typeof action !== 'object') throw new Error('action 必须是一个对象')// 必须有 type 属性if (typeof action.type === 'undefined') throw new Error('action 必须有 type 属性')// 执行 reducer,参数为当前 state 和 action动作,返回新的 stateconst nextState = reducer(state, action)// 更新 公共状态state = nextState// 通知事件池中的方法,更新组件for (let i = 0; i < listeners.length; i++) {const listener = listeners[i]listener()}}// 4.redux初始化statedispatch({ type: '@@redux/INIT' })// 5. 返回 store 对象 { getState, dispatch, subscribe }return {getState,dispatch,subscribe}
}

1. 重要概念

状态是只读的,
后续修改状态的方式是通过Reducer(纯函数)接收旧状态和 Action,返回新状态。
Reducer无副作用,同样的输入必然得到同样的输出。

2. 数据流

  1. 组件通过 dispatch(action) 发送 Action。
  2. Redux 调用对应的 Reducer,生成新状态。
  3. Store 更新状态,通知所有订阅了 Store 的组件。
  4. 组件通过 getState() 获取新状态并重新渲染。

问:Store 更新状态,如何通知组件更新?
通过Store内部的Subscription(listener)方法,listener 通常是 ​触发组件重新渲染的函数,或是 ​与组件更新相关的副作用逻辑。见下:

  1. 类组件:listener 通常是调用 this.forceUpdate() 的函数,强制组件重新渲染。
class Counter extends React.Component {componentDidMount() {// 定义 listener:强制组件重新渲染this.unsubscribe = store.subscribe(() => {this.forceUpdate();});}componentWillUnmount() {this.unsubscribe(); // 取消订阅}render() {const count = store.getState().count;return <div>{count}</div>;}
}
  1. 函数组件:listener 是 useState 的 副作用函数
import React, { useState, useEffect } from 'react';
import store from './store';function Counter() {// 定义forceUpdate 单纯是为了触发组件渲染更新,属性无意义 const [_, forceUpdate] = useState(0);  useEffect(() => {// 定义 listener:强制组件重新渲染const unsubscribe = store.subscribe(() => {forceUpdate(prev => prev + 1);});return unsubscribe; // useEffect 清理函数中取消订阅}, []);const count = store.getState().count;return <div>{count}</div>;
}
  1. 使用 react-redux 的 connect: connect 高阶组件内部会处理订阅逻辑,listener 是​比较新旧 props 并决定是否更新组件的函数。
    connect 是 高阶函数,内部会将公共状态以props的方式传递给组件。
import { connect } from 'react-redux';class Counter extends React.Component {render() {return <div>{this.props.count}</div>;}
}// 映射状态到 props
const mapStateToProps = (state) => ({count: state.count,
});// connect 内部逻辑(简化):
// 1.  Store的监听器会比较新旧 mapStateToProps 的结果。
// 2. 若结果变化,触发组件更新。
export default connect(mapStateToProps)(Counter);
  1. react-redux 的 useSelector钩子
    useSelector 的 listener 是 ​检查选择器返回值是否变化,并触发重新渲染 的函数。
import { useSelector } from 'react-redux';function Counter() {// 内部实现(简化):// 1. 订阅 Store,监听器会比较新旧 selector(state) 的结果。// 2. 若结果变化,触发组件重新渲染。const count = useSelector((state) => state.count);return <div>{count}</div>;
}

❤️❤️❤️ React-Redux

对redux 进行了包装。

  1. <Provider> 组件:Redux Store 注入整个 React 应用,使所有子组件可以访问 Store。
  2. usSelector Hook:从 Store 中获取状态,并自动订阅状态更新,当状态变化时,若返回的值与之前不同,组件会重新渲染。
  3. useDispatch Hook:获取 dispatch 方法,派发 Action
  4. connect 高阶组件(类组件兼容):。
import { connect } from 'react-redux';
import { increment, decrement } from './actions';class Counter extends React.Component {render() {const { count, increment, decrement } = this.props;return (<div><button onClick={decrement}>-</button><span>{count}</span><button onClick={increment}>+</button></div>);}
}// 映射 State 到 Counter的 props,以供取值
const mapStateToProps = (state) => ({count: state.count,
});// 映射 dispatch 到 Counter的 props,以供调用
const mapDispatchToProps = {increment,decrement,
};export default connect(mapStateToProps, mapDispatchToProps)(Counter);

connect :同 useSelector作用一样,为了访问 redux的store

但是这个比较绕一点(兼容了类组件)

  • 输入:一个 React 组件(类 or FC)
  • 输出:一个新的组件,该组件能访问 Redux store
// 模拟 react-redux 的 connect 函数
const connect = (mapStateToProps, mapDispatchToProps) => (WrappedComponent) => {return class Connect extends React.Component {static contextType = ReactReduxContext; // 从 Provider 获取 storeconstructor(props, context) {super(props);this.store = context.store;this.state = {mappedProps: this.calculateProps()};}componentDidMount() {this.unsubscribe = this.store.subscribe(() => {const newMappedProps = this.calculateProps();// 浅比较优化,避免不必要的渲染if (!shallowEqual(this.state.mappedProps, newMappedProps)) {this.setState({ mappedProps: newMappedProps });}});}componentWillUnmount() {this.unsubscribe();}calculateProps() {const state = this.store.getState();const stateProps = mapStateToProps(state);const dispatchProps = mapDispatchToProps(this.store.dispatch);return { ...stateProps, ...dispatchProps };}render() {return <WrappedComponent {...this.props} {...this.state.mappedProps} />;}};
};

combineReducers

组合多个独立 reducer 的核心工具函数

  • 自动分发 Action:
    当一个 action 被 dispatch 时,combineReducers 会 ​自动将该 action 传递给所有子 reducer
import { combineReducers } from 'redux'import FatherAndSonReducer from './FatherAndSonReducer'
import TaskReducer from './TaskReducer'const rootReducer = combineReducers({FatherAndSonReducer,TaskReducer
})export default rootReducer

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

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

相关文章

5.2 位运算专题:LeetCode 268. 丢失的数字

1. 题目链接 LeetCode 268. 丢失的数字 2. 题目描述 给定一个包含 [0, n] 范围内 n 个不同整数的数组 nums&#xff08;实际长度为 n&#xff09;&#xff0c;找出数组中缺失的那个数字。 示例&#xff1a; 输入&#xff1a;nums [3,0,1] → 输出&#xff1a;2&#xff08;…

【Android】VehiclePropertyAccess引起CarService崩溃

VehiclePropertyAccess引起CarService崩溃 VehiclePropertyAccess VehiclePropertyAccess属性&#xff0c;用于定义车辆属性的访问权限。权限包括 读&#xff1a;READ&#xff0c;只可以读取&#xff0c;不能写入。 VehiclePropertyAccess:READ写&#xff1a;WRITE&#xf…

SpringCloud配置中心:Config Server与配置刷新机制

文章目录 引言一、Config Server基础架构1.1 Server端配置1.2 配置文件命名规则 二、Config Client配置2.1 Client端配置2.2 配置注入与使用 三、配置刷新机制3.1 手动刷新配置3.2 使用Spring Cloud Bus实现自动刷新3.3 配置仓库Webhook自动触发刷新 四、高级配置管理策略4.1 配…

PyTorch生成式人工智能实战:从零打造创意引擎

PyTorch生成式人工智能实战&#xff1a;从零打造创意引擎 0. 前言1. 生成式人工智能1.1 生成式人工智能简介1.2 生成式人工智能技术 2. Python 与 PyTorch2.1 Python 编程语言2.2 PyTorch 深度学习库 3. 生成对抗网络3.1 生成对抗网络概述3.2 生成对抗网络应用 4. Transformer4…

【计算机网络】-计算机网络期末复习题复习资料

一、计算机网络体系结构&#xff08;800字&#xff09; 1. OSI参考模型 七层结构&#xff1a;物理层→数据链路层→网络层→传输层→会话层→表示层→应用层 各层核心功能&#xff1a; 物理层&#xff1a;比特流传输&#xff08;如RJ45、光纤接口&#xff09; 数据链路层&…

31天Python入门——第9天:再学函数

你好&#xff0c;我是安然无虞。 文章目录 再学函数1. 变量在函数中的作用域2. 函数的参数传递.补充学习: 不定长参数*args和**kwargs 3. 值传递和引用传递补充学习: 把函数作为参数传递 4. 匿名函数5. python中内置的常用函数zip()map()filter()all()any() 6. 函数练习 再学函…

EasyUI数据表格中嵌入下拉框

效果 代码 $(function () {// 标记当前正在编辑的行var editorIndex -1;var data [{code: 1,name: 1,price: 1,status: 0},{code: 2,name: 2,price: 2,status: 1}]$(#dg).datagrid({data: data,onDblClickCell:function (index, field, value) {var dg $(this);if(field ! …

【C语言】多进程/多线程

【C语言】多进程/多线程 参考链接多进程/多线程服务器1. 多进程服务器2. 多线程服务器 结语参考链接 参考链接 c 中文网 菜鸟 c 多进程/多线程服务器 多进程和多线程是常用的并发编程技术。它们都允许程序同时执行多个任务&#xff0c;提高了系统的资源利用率和程序的运行效率…

mysql 磐维(opengauss)tidb误删数据之高级恢复

Mysql参考&#xff1a; Mysql 8.0 XtraBackupMysqlbinlog 完全恢复 - 墨天轮 Mysql 8.0 XtraBackupMysqlbinlog 完全恢复[TOC]# 一、安装mysql 8.0.19## 1.1https://www.modb.pro/db/509223MySQL 的全量备份、增量备份与 Binlog 时间点恢复_mysqlbinlog自动备份吗-CSDN博客文章…

3. 轴指令(omron 机器自动化控制器)——>MC_SetPosition

机器自动化控制器——第三章 轴指令 11 MC_SetPosition变量▶输入变量▶输出变量▶输入输出变量 功能说明▶时序图▶重启动运动指令▶多重启运动指令▶异常 MC_SetPosition 将轴的指令当前位置和反馈当前位置变更为任意值。 指令名称FB/FUN图形表现ST表现MC_SetPosition当前位…

MySQL面试专题

1.什么是BufferPool&#xff1f; Buffer Pool基本概念 Buffer Pool&#xff1a;缓冲池&#xff0c;简称BP。其作用是用来缓存表数据与索引数据&#xff0c;减少磁盘IO操作&#xff0c;提升效率。 Buffer Pool由缓存数据页(Page) 和 对缓存数据页进行描述的控制块 组成, 控制…

调用百度api实现语音识别(python)

该代码实现了一个企业级的语音识别解决方案,通过调用百度语音识别API,实现实时录音识别和对已有音频语音识别功能。 百度智能云:请自行访问百度智能云,开通免费的语音识别功能,获取API_KEY和SECRET_KEY。操作按照百度流程即可,可免费申请。 首先,配置下百度API和描述下错…

KRaft模式

目录标题 Kraft模式**1. 什么是Kraft模式&#xff1f;****2. 为什么引入Kraft模式&#xff1f;****3. 核心优势****4. 架构与工作原理****5. 部署与配置要点****6. 适用场景与最佳实践****总结**KIP-833: Mark KRaft as Production Ready除了Kraft模式&#xff0c;Kafka还有以下…

常见框架漏洞之一:Thinkphp5x

ThinkPHP是为了简化企业级应⽤开发和敏捷WEB应⽤开发⽽诞⽣的&#xff0c;是⼀个快速、兼容⽽且简单的轻量级国产PHP开发框架&#xff0c;诞⽣于2006年初&#xff0c;原名FCS&#xff0c;2007年元旦正式更名为 ThinkPHP&#xff0c;遵循Apache2开源协议发布&#xff0c;从Stru…

2025年优化算法:龙卷风优化算法(Tornado optimizer with Coriolis force,TOC)

龙卷风优化算法&#xff08;Tornado optimizer with Coriolis force&#xff09;是发表在中科院二区期刊“ARTIFICIAL INTELLIGENCE REVIEW”&#xff08;IF&#xff1a;11.7&#xff09;的2025年智能优化算法 01.引言 当自然界的狂暴之力&#xff0c;化身数字世界的智慧引擎&…

Mysql表的简单操作

&#x1f3dd;️专栏&#xff1a;Mysql_猫咪-9527的博客-CSDN博客 &#x1f305;主页&#xff1a;猫咪-9527-CSDN博客 “欲穷千里目&#xff0c;更上一层楼。会当凌绝顶&#xff0c;一览众山小。” 目录 3.1 创建表 3.2 查看表结构 3.3 修改表 1. 添加字段 2. 修改字段 3…

【云馨AI-大模型】自动化部署Dify 1.1.2,无需科学上网,Linux环境轻松实现,附Docker离线安装等

Dify介绍 官网&#xff1a;https://dify.ai/zh生成式 AI 应用创新引擎开源的 LLM 应用开发平台。提供从 Agent 构建到 AI workflow 编排、RAG 检索、模型管理等能力&#xff0c;轻松构建和运营生成式 AI 原生应用。 Dify安装脚本 目录创建 mkdir -p /data/yunxinai &&a…

人脸表情识别系统分享(基于深度学习+OpenCV+PyQt5)

最近终于把毕业大论文忙完了&#xff0c;众所周知硕士大论文需要有三个工作点&#xff0c;表情识别领域的第三个工作点一般是做一个表情识别系统出来&#xff0c;如下图所示。 这里分享一下这个表情识别系统&#xff1a; 采用 深度学习OpenCVPyQt5 构建&#xff0c;主要功能包…

GitHub供应链攻击事件:Coinbase遭袭,218个仓库暴露,CI/CD密钥泄露

此次供应链攻击涉及GitHub Action "tj-actions/changed-files"&#xff0c;最初是针对Coinbase的一个开源项目的高度定向攻击&#xff0c;随后演变为范围更广的威胁。 攻击过程与影响 Palo Alto Networks Unit 42在一份报告中指出&#xff1a;“攻击载荷主要针对其…

GZCTF平台搭建及题目上传

前言 我用手里的Ubuntu虚拟机搭建的&#xff0c;大家根据自己的实际情况来吧 安装及部署 首先&#xff0c;你的虚拟机需要有Docker和Docker-Compose&#xff0c;前者可以看我之前的文章&#xff0c;另外一个可以输入下面的命令安装&#xff0c;注意先获取管理员权限&#xff…