在React中,useContext 是一种非常方便的全局状态管理工具,它可以让我们在组件之间共享状态,而不需要通过层层传递 props。然而,当我们在一个大型的 React 应用中过度使用 useContext 时,可能会遇到性能问题。这是因为当一个 context 的值改变时,所有使用这个 context 的组件都会重新渲染,即使这个组件并不需要那个改变的值。

示例

举个例子,假设我们有一个全局的用户 context,它包含了用户的详细信息和一些设置:

const UserContext = React.createContext();

function App() {
const [user, setUser] = useState({ name: 'John', age: 30, theme: 'dark' }); const handleChangeName = () => {
setUser({ ...user, name: 'AAA' });
};
return (
<UserContext.Provider value={user}>
<Profile />
<Settings />
<button onClick={handleChangeName}>Change Name</button>
</UserContext.Provider>
);
} function Profile() {
const user = useContext(UserContext); return <h1>Welcome, {user.name}!</h1>;
} function Settings() {
const user = useContext(UserContext); return <div>Your current theme is: {user.theme}</div>;
}

在这个例子中,Profile 和 Settings 组件都使用了 UserContext。如果用户的主题改变了,Profile 组件也会重新渲染,即使它并不需要知道主题的信息。

改进方法

一种改进方法是使用 React 的 useMemouseCallback钩子来避免不必要的重新渲染。我们可以为每一个需要共享的状态创建一个单独的 context,然后使用 useMemo useCallback 来确保只有当这个状态改变时,使用这个状态的组件才会重新渲染:

const NameContext = React.createContext();
const ThemeContext = React.createContext(); function App() {
console.log('App');
const [user, setUser] = useState({ name: 'John', age: 30, theme: 'dark' }); const userName = useMemo(() => user.name, [user.name]);
const userTheme = useMemo(() => user.theme, [user.theme]); const handleChangeName = useCallback(() => {
setUser({ ...user, name: 'AAA' });
}, [user]); return (
<>
<NameContext.Provider value={userName}>
<ThemeContext.Provider value={userTheme}>
<Profile />
<Settings />
<button onClick={handleChangeName}>Change Name</button>
</ThemeContext.Provider>
</NameContext.Provider>
</>
);
}
const Profile = React.memo(function Profile() {
console.log('Profile');
const name = useContext(NameContext); return <h1>Welcome, {name}!</h1>;
}); const Settings = React.memo(function Settings() {
console.log('Settings');
const theme = useContext(ThemeContext); return <h1>Your current theme is: {theme}</h1>;
});

这样,只有当相关的状态改变时,对应的组件才会重新渲染,从而提高了性能。

举例useContext性能低下的样例,同时推荐用什么方法改进的更多相关文章

  1. Qt 鼠标样式特效探索样例(一)——利用时间器调用QWidget.move()函数

    Qt 鼠标样式特效探索样例(一)       心血来潮,突然想在Qt里玩一把鼠标样式,想到在浏览网页时,经常看到漂亮的鼠标动画,于是今天摸索着乱写个粗糙的demo,来满足自己的好奇心. 效果图 方案要 ...

  2. C++的性能C#的产能?! - .Net Native 系列《三》:.NET Native部署测试方案及样例

    之前一文<c++的性能, c#的产能?!鱼和熊掌可以兼得,.NET NATIVE初窥> 获得很多朋友支持和鼓励,也更让我坚定做这项技术的推广者,希望能让更多的朋友了解这项技术,于是先从官方 ...

  3. 【Scala篇】--Scala中Trait、模式匹配、样例类、Actor模型

    一.前述 Scala Trait(特征) 相当于 Java 的接口,实际上它比接口还功能强大. 模式匹配机制相当于java中的switch-case. 使用了case关键字的类定义就是样例类(case ...

  4. JPA入门样例(採用JPA的hibernate实现版本号)

    (1).JPA介绍: JPA全称为Java Persistence API ,Java持久化API是Sun公司在Java EE 5规范中提出的Java持久化接口.JPA吸取了眼下Java持久化技术的长 ...

  5. RESTful设计原则和样例(开发前后台接口)

    摘要 REST(表征性状态传输)设计风格;REST通常基于使用HTTP,URI协议和标准.使用URL标识资源,开发前后台接口.主要使用post,get方式 参考博文: http://www.cnblo ...

  6. CloudSim样例分析

    自带八个样例描述: cloudsim-2.1.1\examples目录下提供了一些CloudSim样例程序,每个样例模拟的环境如下: (1)CloudSimExample1.Java:创建一个一台主机 ...

  7. Ajax框架,DWR介绍,应用,样例

    使用Ajax框架 1. 简化JavaScript的开发难度 2. 解决浏览器的兼容性问题 3. 简化开发流程 经常使用Ajax框架 Prototype 一个纯粹的JavaScript函数库,对Ajax ...

  8. 最简单的视音频播放演示样例5:OpenGL播放RGB/YUV

    ===================================================== 最简单的视音频播放演示样例系列文章列表: 最简单的视音频播放演示样例1:总述 最简单的视音频 ...

  9. VC6 鼠标钩子 最简单样例

    Windows系统是建立在事件驱动的机制上的,说穿了就是整个系统都是通过消息的传递来实现的.而钩子是Windows系统中非常重要的系统接口,用它能够截获并处理送给其它应用程序的消息,来完毕普通应用程序 ...

  10. SQL SERVER 变量的使用和样例

    定义和使用局部变量:说明: 局部变量是用户可自定义的变量. 作用范围仅在程序内部. 局部变量的名称是用户自定义的,命名的局部变量名要符合SQL Server 2000标识符命名规则=>以@开 在 ...

随机推荐

  1. 大模型时代的PDF解析工具

    去年(2023年)是大模型爆发元年.但是大模型具有两个缺点:缺失私有领域知识和幻觉.缺失私有领域知识是指大模型训练时并没有企业私有数据/知识,所以无法正确回答相关问题.并且在这种情况下,大模型会一本正 ...

  2. SqlServer查询表的所有字段属性及其是否是主外键

    CREATE PROC [dbo].[sp_help2] @TableName VARCHAR(50) = NULL AS SET NOCOUNT ON SET TRANSACTION ISOLATI ...

  3. java 计算两个日期相差工作日天数

    import java.text.ParseException; import java.text.SimpleDateFormat; import java.time.DayOfWeek; impo ...

  4. KingabseES 隐式游标属性值(SQL%attribute)

    隐式游标介绍 Oracle数据库迁移到KingbaseES数据库,不需要将源PL/SQL脚本,大规模修改为KES语法,因为KingbaseES支持大部分PLSQL语法. 1.隐式游标 隐式游标是由 P ...

  5. KingbaseES 数据库安装报错案例分析

    Linux系统安装V008R006C007B0012版本KingbaseES数据库报错:Unsupported major.minor version 52.0 系统版本: [root@vm-10-3 ...

  6. JDK9的新特性:JVM的xlog

    目录 简介 xlog的使用 selections output decorators 总结 简介 在java程序中,我们通过日志来定位和发现项目中可能出现的问题.在现代java项目中,我们使用log4 ...

  7. Apache Maven ToolChains的使用

    目录 简介 Toolchains的介绍 Toolchains的例子 Toolchains支持 总结 简介 Maven是java中非常有用和常用的构建工具,基本上现在大型的java项目都是Maven和g ...

  8. 深入理解 SQL UNION 运算符及其应用场景

    SQL UNION运算符 SQL UNION运算符用于组合两个或多个SELECT语句的结果集. 每个UNION中的SELECT语句必须具有相同数量的列. 列的数据类型也必须相似. 每个SELECT语句 ...

  9. 有奖调研 | 让虚拟照入现实的完美AR开发平台长什么样?

    6年前的夏天,一款现实与虚拟结合的手游成了无数玩家的心头好,手握智能手机,玩家就能在真实世界来一场妙趣横生的探险,收集动漫作品里如数家珍的宠物精灵.AR技术结合用户熟识喜爱的内容形式,与现实环境中扩充 ...

  10. Python数据分析 numpy 笔记

     B站课链接:[Python数据分析三剑客:NumPy.Pandas与Matplotlib] https://www.bilibili.com/video/BV1Yb4y1g7SV/?p=16& ...