React的API✅

createContext

createContext要和useContext配合使用,可以理解为 “React自带的redux或mobx” ,事实上redux就是用context来实现的。但是一番操作下来我还是感觉,简单的context对视图的更新的细粒度把控比不上mobx,除非配合memo等优化手段来优化。(redux只用过一次不是很会👋)

以下demo介绍context的简单使用:

// store.ts
import { createContext } from "react";
export const ThemeContext = createContext({theme: "light",setTheme: (_theme: string): void => {},
});
export const AuthContext = createContext({name: "boyiao",roleType: "admin",setRoleType: (_roleType: string): void => {},setName: (_name: string): void => {},
});
// Demo.js
import { useContext, useState } from "react";
import { ThemeContext, AuthContext } from "./store";const PageA = () => {console.log("Page Render");const { theme, setTheme } = useContext(ThemeContext);const { name, setName, roleType, setRoleType } = useContext(AuthContext);return (<div><button onClick={() => setTheme(theme === "light" ? "dark" : "light")}>Set Theme In Page</button><div>{theme}</div><div>{name}</div></div>);
};const OtherPage = () => {console.log("OtherPage Render");return (<div style={{ border: "1px solid red" }}><div>OtherPage</div></div>);
};function Demo() {const [theme, setTheme] = useState("light");const [name, setName] = useState("boyiao");const [roleType, setRoleType] = useState("admin");console.log("App Render");return (<><ThemeContext.Provider value={{ theme, setTheme }}><AuthContext.Provider value={{ name, setName, roleType, setRoleType }}><button onClick={() => setTheme(theme === "light" ? "dark" : "light")}>Change Theme</button><button onClick={() => setRoleType(roleType === "admin" ? "user" : "admin")}>Change Auth</button><Page /></AuthContext.Provider></ThemeContext.Provider><OtherPage /> // 注意这玩意在Context之外</>);
}export default Demo;

为什么说“简单的context对视图的更新的细粒度把控比不上mobx”?项目中常见的情况是,我们有一些需要在全局共享的状态需要管理如userName、roleType、themeToken等,如果用context来管理,为了保证这些变量可改变并触发视图重新渲染,我们不得不在根组件里用useState来保存这些全局变量。但是如果这些全局的变量改变,重新渲染影响到的范围是从最顶层往下的,成本未免太高。
见上面那个demo,OtherPage不会用到context中的变量,但是每次全局变量更新,OtherPage也要重新渲染。

但是当然有办法解决, 用memo、useMemo来缓存就好了;或者我们把需要共享的变量进行一些作用域的划分,即不要把所有需要共享的变量都生命在Root组件里面,这些都是为了降低重绘(排)的成本, 只是需要在别的地方下点功夫。只是如果用mobx则方便很多,因为mobx要求开发者用observer来显示地绑定要监听的组件:

// store.ts
import { observable, configure, action } from "mobx";
configure({ enforceActions: "always" });
interface AccountMobx {userName: string;roleType: "admin" | "user";setUserName: (name: string) => void;setRoleType: (role: "admin" | "user" ) => void;
}
const accountMobx = observable<AccountMobx>({userName: "boyiao",roleType: "admin",setUserName(name: string) {this.userName = name;},setRoleType(role: "admin" | "user" ) {this.roleType = role;},},{setUserName: action,setRoleType: action}
);
export default accountMobx;
import { observer } from "mobx-react-lite";
import accountMobx from "./store";
const Demo = observer(() => {console.log("Demo render");return (<div><div>{accountMobx.userName}</div><buttononClick={() => accountMobx.setUserName(accountMobx.userName + "1")}>set userName</button></div>);
});
export default Demo;
import "./App.css";
import Demo from './ReactMobxDemo/index.tsx'
function App() {console.log("App rendered");return (<><Demo /><div className="App">// App Content</div></>);
}
export default App;

这样的好处很直接:Demo的更新影响不到App中的其他内容。


错误边界

只用过类组件的,主要借助类组件的 componentDidCatch (他可以捕获子组件渲染过程中的错误,并在渲染组件树的过程中向上冒泡,直到它被捕获为止。)生命周期。函数组件要实现这种功能相对复杂。

import React from "react";
class ErrorBoundary extends React.Component {constructor(props) {super(props);this.state = { hasError: false };}static getDerivedStateFromError(error) {// 更新状态以干掉后续的渲染return { hasError: true };}componentDidCatch(error, errorInfo) {// 可以在此处记录错误信息console.error("错误捕获:", error, errorInfo);}render() {if (this.state.hasError) {// 自定义的降级 UIreturn <h1>出了点问题,请稍后再试。</h1>;}return this.props.children;}
}

伟大无需多言。


createPoral(React DOM的API)

最近发布了一个图钉组件📌到npm上面,这个组件的实现就是借助了createPoral。

portal 允许组件将它们的某些子元素渲染到 DOM 中的不同位置。这使得组件的一部分可以“逃脱”它所在的容器。例如组件可以在页面其余部分上方或外部显示模态对话框和提示框。
portal 只改变 DOM 节点的所处位置。在其他方面,渲染至 portal 的 JSX 的行为表现与作为 React 组件的子节点一致。该子节点可以访问由父节点树提供的 context 对象、事件将从子节点依循 React 树冒泡到父节点。

考虑下面这个需求:在我的React应用中有一个比待标记的节点,我希望将它标记出来:即在页面的空白处打上一个「图钉」,并将「图钉」与这个「待标记的节点」用线连接(怎么画线先不管,在我的组件里我用div来做,这么简单怎么来)。
然后我希望实现的代码逻辑如下:

const HomePage = () => {return (<div id="container"><div id="targetDOM">这是你想要连接的元素</div><ThumbtackpopupContainerId="container"targetElementId="targetDOM"></Thumbtack></div>);
};

问题来了:Thumbtack要如何封装,才能让他里面的某些DOM节点跑到#container里面,和#targetDOM产生交互?这就是createPoral的作用。

const Thumbtack = ({popupContainerId,targetElementId
}: { popupContainerId: string,targetElementId: string
}) => {const [popupContainer, setPopupContainer] = useState(null);useEffect(() => {const popupRef = document.getElementById(popupContainerId);popupRef && setPopupContainer(popupRef);}, [])return (<div id='thumbtack'>{ popupContainer && createPortal(<div>📌</div>, popupContainer) }</div>)
}

最基本的思路就如上面这样简单,把📌挂载到和#targetDOM的同一个父节点下面,方便后续的绝对定位、transform等操作。但是createPoral改变的只是DOM元素渲染的位置,在上面那个Thumbtack中,< div>📌< /div>可以使用在Thumbtack里面定义的变量,而且他的事件冒泡也是冒泡到#thumbtack那里,而非#container那里。


forwardRef

forwardRef最常见的还是配合useImperativeHandle一块用,但单独使用也可以把自组件的某些DOM节点暴露给父组件。我都懒得写了直接看人家React官网吧。


keep-alive在react里如何实现?

  • 现有的方案:react-activation
  • 推荐关注的:React18 的 Offscreen
  • 自己实现:保留关键数据(如滚动的距离、需要记录的关键状态……)

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

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

相关文章

VUE字符串转日期加天数

文章为本新手菜鸡的问题记录&#xff0c;如有错误和不足还行大佬指正 文章目录 问题描述解决方法 问题描述 得到一串字符串的日期&#xff0c;因为不是规范的日期格式&#xff0c;无法使用moment().add()方法&#xff0c;那么如何实现增加天数的操作&#xff1f; 解决方法 1…

高校企业数据挖掘平台推荐

TipDM数据挖掘建模平台是由广东泰迪智能科技股份有限公司自主研发打造的可视化、一站式、高性能的数据挖掘与人工智能建模服务平台&#xff0c;致力于为使用者打通从数据接入、数据预处理、模型开发训练、模型评估比较、模型应用部署到模型任务调度的全链路。平台内置丰富的机器…

《TCP/IP网络编程》学习笔记 | Chapter 14:多播与广播

《TCP/IP网络编程》学习笔记 | Chapter 14&#xff1a;多播与广播 《TCP/IP网络编程》学习笔记 | Chapter 14&#xff1a;多播与广播多播多播的数据传输方式和特点路由&#xff08;Routing&#xff09;和 TTL&#xff08;Time to Live&#xff0c;生存时间&#xff09;&#xf…

利用 TensorFlow Profiler:在 AMD GPU 上优化 TensorFlow 模型

TensorFlow Profiler in practice: Optimizing TensorFlow models on AMD GPUs — ROCm Blogs 简介 TensorFlow Profiler 是一组旨在衡量 TensorFlow 模型执行期间资源利用率和性能的工具。它提供了关于模型如何与硬件资源交互的深入见解&#xff0c;包括执行时间和内存使用情…

游戏引擎学习第15天

视频参考:https://www.bilibili.com/video/BV1mbUBY7E24 关于游戏中文件输入输出&#xff08;IO&#xff09;操作的讨论。主要分为两类&#xff1a; 只读资产的加载 这部分主要涉及游戏中用于展示和运行的只读资源&#xff0c;例如音乐、音效、美术资源&#xff08;如 3D 模型和…

(二)Ubuntu22.04+Stable-Diffusion-webui AI绘画 中英双语插件安装

一、说明 看情况添加 二、双语安装 双语插件 https://github.com/journey-ad/sd-webui-bilingual-localization 中文语言包 https://github.com/dtlnor/stable-diffusion-webui-localization-zh_CN 先装中文语言包 错误&#xff1a;AssertionError: extension access disable…

UE5 DownloadImage加载jpg失败的解决方法

DownloadImage加载jpg失败的解决方法 现象解决方案具体方法 现象 用UE自带的 DownloadImage 无法下载成功&#xff0c;从 failure 引脚出来。 接入一个由监控器自动保存起的图像&#xff0c;有些可以正常加载成功&#xff0c;有些无法加载成功。 经调查问题出现在&#xff0c;…

Elasticsearch 中的热点以及如何使用 AutoOps 解决它们

作者&#xff1a;来自 Elastic Sachin Frayne 探索 Elasticsearch 中的热点以及如何使用 AutoOps 解决它。 Elasticsearch 集群中出现热点的方式有很多种。有些我们可以控制&#xff0c;比如吵闹的邻居&#xff0c;有些我们控制得较差&#xff0c;比如 Elasticsearch 中的分片分…

Statsmodels之OLS回归

目录 Statsmodels基本介绍OLS 回归实战实战1&#xff1a;实战2&#xff1a; Statsmodels基本介绍 Statsmodels 是 Python 中一个强大的统计分析包&#xff0c;包含了回归分析、时间序列分析、假设检验等等的功能。Statsmodels 在计量的简便性上是远远不及 Stata 等软件的&…

【接口封装】—— 1、加载样式表

函数定义 static void loadStyleSheet(QWidget* widget, const QString &fileName,const QString& otherStyleQString());&#xff08;头文件&#xff09;&#xff1a; #include <qfile.h> #include <QWidget> 源文件: void CommonUtils::loadStyleSheet(…

AI、VR与空间计算:教育和文旅领域的数字转型力量

在这个数字技术高速发展的时代&#xff0c;AI、VR技术及大空间计算技术&#xff0c;已成为推动多个行业革新的强劲动力。近日&#xff0c;世优科技推出了最新研发的VR大空间产品《山海经》&#xff0c;这一全新的沉浸式体验项目不仅重新定义了观展方式&#xff0c;还为文化旅游…

AWTK 最新动态:支持鸿蒙系统(HarmonyOS Next)

HarmonyOS是全球第三大移动操作系统&#xff0c;有巨大的市场潜力&#xff0c;在国产替代的背景下&#xff0c;机会多多&#xff0c;AWTK支持HarmonyOS&#xff0c;让AWTK开发者也能享受HarmonyOS生态的红利。 AWTK全称为Toolkit AnyWhere&#xff0c;是ZLG倾心打造的一套基于C…

数据库、数据仓库、数据湖、数据中台、湖仓一体的概念和区别

数据库、数据仓库、数据湖、数据中台和湖仓一体是数据管理和分析领域的不同概念&#xff0c;各自有不同的特点和应用场景。以下是它们的主要区别&#xff1a; 1. 数据库&#xff08;Database&#xff09; 定义&#xff1a;结构化的数据存储系统&#xff0c;用于高效地存储、检…

Linux运维篇-iscsi存储搭建

目录 概念实验介绍环境准备存储端软件安装使用targetcli来管理iSCSI共享存储 客户端软件安装连接存储 概念 iSCSI是一种在Internet协议上&#xff0c;特别是以太网上进行数据块传输的标准&#xff0c;它是一种基于IP Storage理论的存储技术&#xff0c;该技术是将存储行业广泛…

Django一分钟:django中收集关联对象关联数据的方法

场景&#xff1a;我有一个模型&#xff0c;被其它多个模型关联&#xff0c;我配置了CASCADE级联删除&#xff0c;我想要告知用户删除该实例之后&#xff0c;哪些关联数据将会被一同删除。 假设我们当前有这样一组模型&#xff1a; class Warehouse(models.Model):""…

iPhone 17 Air看点汇总:薄至6mm 刷新苹果轻薄纪录

我们姑且将这款iPhone 17序列的超薄SKU称为“iPhone 17 Air”&#xff0c;Jeff Pu在报告中提到&#xff0c;我同意最近关于 iPhone 17超薄机型采用6 毫米厚度超薄设计的传言。 如果这一测量结果被证明是准确的&#xff0c;那么将有几个值得注意的方面。 首先&#xff0c;iPhone…

Tcp协议Socket编程

&#x1f30e; Tcp协议Socket编程 本次socket编程需要使用到 日志文件&#xff0c;此为具体日志编写过程。以及 线程池&#xff0c;线程池原理比较简单&#xff0c;看注释即可。 文章目录&#xff1a; Tcp协议Socket编程 TCP Socket API简介 构建Tcp_echo_server      …

嵌入式系统中QT实现网络通信方法

大家好,今天主要给大家分享一下,如何使用QT中的网络编程实现。 第一:QT网络编程基本简介 QT中网络模块为提供了可以使用TCP/IP客户端与服务器的类。它提供了较低级别的类,例如代表低级网络概念的 QTcpSocket, QTcpServer 和 QUdpSocket,以及诸如 QNetworkRequest, QNetw…

【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现(Kalman Filter)

【卡尔曼滤波】数据预测Prediction观测器的理论推导及应用 C语言、Python实现&#xff08;Kalman Filter&#xff09; 更新以gitee为准&#xff1a; 文章目录 数据预测概念和适用方式线性系统的适用性 数据预测算法和卡尔曼滤波公式推导状态空间方程和观测器先验估计后验估计…

大模型时代的具身智能系列专题(十三)

迪士尼研究中心 瑞士苏黎世迪斯尼研究中心致力于不同领域的业务活动&#xff0c;其中包括电影、电视、公园和度假村以及消费产品。我们针对所有这些领域进行科研工作。我们开发能使我们将后道生产元素整合到前级生产中的技术。由此可节省许多昂贵的效果&#xff0c;这些效果最…