React Hooks实战:从useState到useContext深度解析

useState和useContext深度解析

React Hooks 彻底改变了React组件的状态管理和功能复用方式,使得函数组件也能拥有类组件的功能。

useState:函数组件的状态管理

简介:

useState是React中最基础的Hook,它允许我们在函数组件中添加状态。useState是React提供的一个内置Hook,用于在函数组件中添加局部状态。它接受一个初始值作为参数,返回一个数组,数组的第一个元素是当前状态,第二个元素是一个更新状态的函数。

import React, { useState } from 'react';function Example() {// 初始化状态count为0const [count, setCount] = useState(0);return (<div><p>You clicked {count} times</p><button onClick={() => setCount(count + 1)}>Click me</button></div>);
}

useState 返回的 setCount 函数用于更新状态。每次调用 setCount 时,React会重新渲染组件,并根据新的状态值重新生成虚拟DOM,然后进行高效的DOM diff,最终更新实际DOM。

深入理解

useState的工作原理,状态更新的异步性及其对性能的影响。

  • 状态更新是异步的,这意味着在同一个事件循环中多次调用 setCount,React只会使用最后一次的值。
  • useState 不支持复杂对象的浅比较,如果需要基于前一个状态更新状态,可以使用函数形式的 setCount,例如 setCount(prevCount => prevCount + 1)
进阶应用

结合useEffect处理副作用,如数据获取与清理。

import React, { useState, useEffect } from 'react';function Example() {// 初始化状态const [data, setData] = useState(null);const [loading, setLoading] = useState(true);const [error, setError] = useState(null);// 数据获取函数const fetchData = async () => {try {setLoading(true);const response = await fetch('https://api.example.com/data');const json = await response.json();setData(json);setError(null);} catch (err) {setError(err.message);setData(null);} finally {setLoading(false);}};// useEffect监听data的变化,首次渲染时执行useEffect(() => {fetchData();}, []);// 渲染UIif (loading) {return <div>Loading...</div>;}if (error) {return <div>Error: {error}</div>;}return (<div><h1>Data Retrieved Successfully</h1><pre>{JSON.stringify(data, null, 2)}</pre></div>);
}export default Example;

代码示例解读:首先使用 useState 创建了三个状态变量:data 存储获取的数据,loading 表示数据是否正在加载,error 存储任何可能出现的错误信息。

然后,我们定义了一个 fetchData 函数,用于异步获取数据。这个函数中包含了错误处理和状态更新逻辑。

接着,我们使用 useEffect 来执行数据获取。useEffect 的第二个参数是一个依赖数组,这里传入空数组意味着只在组件挂载后执行一次,即首次渲染时获取数据。这样可以确保在组件加载时获取数据,而不是在每次状态更新时都重新获取。

useEffect 的回调函数中,我们调用 fetchData 函数。由于 fetchData 改变了 dataloadingerror 的值,所以不需要将这些状态变量添加到依赖数组中,因为它们的变化会触发组件的重新渲染,从而自动执行新的数据获取。

useContext:共享状态的上下文解决方案

简介

useContext用于跨组件传递数据,无需显式传递props。

首先,我们需要创建一个Context:

import React from 'react';const ThemeContext = React.createContext('light');

然后在组件中使用 useContext:

import React, { useContext } from 'react';
import { ThemeContext } from './ThemeContext';function Button() {const theme = useContext(ThemeContext);return (<button style={{ backgroundColor: theme === 'dark' ? 'black' : 'white' }}>{theme === 'dark' ? 'Dark' : 'Light'}</button>);
}
深入理解
  • 使用 useContext的组件会在提供者(Provider)更新时重新渲染,即使该组件的其他状态没有变化。
  • 如果多个组件订阅同一个Context,它们都会在提供者状态改变时重新渲染,可能导致不必要的性能开销。可以通过React.memoshouldComponentUpdate等策略优化。
  • 为了防止滥用,只在需要跨多个层级共享状态时使用Context,否则应优先考虑props传递。

useState与useContext的组合应用

结合 useStateuseContext,我们可以创建一个带有主题切换功能的计数器应用:

import React, { createContext, useState, useContext } from 'react';// 创建ThemeContext
const ThemeContext = createContext('light');function ThemeProvider({ children }) {const [theme, setTheme] = useState('light');return (<ThemeContext.Provider value={theme}>{children}<button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>Toggle Theme</button></ThemeContext.Provider>);
}function Counter() {const theme = useContext(ThemeContext);const [count, setCount] = useState(0);return (<div style={{ backgroundColor: theme === 'dark' ? 'black' : 'white' }}><h1>{count}</h1><button onClick={() => setCount(count + 1)}>Click me ({theme})</button></div>);
}function App() {return (<ThemeProvider><Counter /></ThemeProvider>);
}export default App;

代码示例解读:ThemeProvider 使用 useState 管理主题状态,Counter 组件通过 useContext 订阅主题,同时使用 useState 管理计数器状态。当主题切换时,Counter 会重新渲染,显示对应主题的颜色。

2500G计算机入门到高级架构师开发资料超级大礼包免费送!

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

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

相关文章

鸿蒙HarmonyOS开发:List列表组件的使用详解及案例演示(二)

文章目录 一、List组件简介1、List组件2、ListItem组件3、ListItemGroup组件 二、使用ForEach渲染列表三、设置列表分割线四、设置List排列方向五、索引值计算规则六、示例演示1、AlphabetIndexer组件2、代码3、效果 一、List组件简介 在我们常用的手机应用中&#xff0c;经常…

OceanBase OAT安装

本文介绍如何 Docker 部署 OAT。 前提条件 在部署 OAT 之前&#xff0c;您需要确认以下信息&#xff1a; 您的操作系统满足以下条件&#xff1a; 服务器类型操作系统支持版本x86_64RHEL7.2 及以上版本x86_64CentOS7.2 及以上版本x86_64AliOS7.2 及以上版本x86_64openSUSE12SP…

SinoDB数据库导入导出工具External table

External table又叫SinoDB外部表&#xff0c;外部表采用多线程机制&#xff0c;支持多线程读取、写入数据文件以及多线程数据转换、插入操作。多线程机制只需要消耗相对较少的系统资源&#xff0c;但是能提供高速数据导入、导出&#xff0c;可以应用在数据采集、表重建、数据库…

OpenGL入门第四步:摄像机视角变换与交互

OpenGL入门第一步:创建窗口、重写虚函数-CSDN博客 OpenGL入门第二步:颜色、纹理设置(解析)-CSDN博客 OpenGL入门第三步:矩阵变换、坐标系统-CSDN博客 目录 函数解析 具体代码 函数解析 相机视角变换需要与鼠标键盘进行交互,需要重写鼠标和键盘响应函数。 初始化 …

【机器学习】 人工智能和机器学习辅助决策在空战中的未来选择

&#x1f680;传送门 &#x1f680;文章引言&#x1f512;技术层面&#x1f4d5;作战结构&#x1f308;替代决策选项&#x1f3ac;选项 1&#xff1a;超级战争&#xff08;Hyperwar&#xff09;&#x1f320;选项 2&#xff1a;超越OODA&#x1f302;选项 3&#xff1a;阻止其他…

MySQL的表级锁

&#x1f4dd;个人主页&#xff1a;五敷有你 &#x1f525;系列专栏&#xff1a;面经 ⛺️稳中求进&#xff0c;晒太阳 表级锁 介绍 对于表锁&#xff0c;分为两类&#xff1a; 表共享读锁表独占写锁 语法 1. 加锁&#xff1a;lock tables 表名... read/write 2.…

MySQL数据库的安装和部署

1.数据库的相关介绍 关系型数据库管理系统&#xff1a;&#xff08;英文简称&#xff1a;RDBMS&#xff09; 为我们提供了一种存储数据的特定格式&#xff0c;所谓的数据格式就是表&#xff0c; 在数据库中一张表就称为是一种关系. 在关系型数据库中表由两部分组成&#xf…

电信网关配置管理系统 rewrite.php 文件上传致RCE漏洞复现

0x01 产品简介 中国电信集团有限公司(英文名称“China Telecom”、简称“中国电信”)成立于2000年9月,是中国特大型国有通信企业、上海世博会全球合作伙伴。电信网关配置管理系统是一个用于管理和配置电信网络中网关设备的软件系统。它可以帮助网络管理员实现对网关设备的远…

threejs 根据离散点生成不规则三角网(三角剖分),检测点是否在该三角网内(区域搜索)

我们知道threejs中的模型都是一个个三角网组成的&#xff0c;三角网数量越多&#xff0c;模型就越精细。 在 Three.js 中&#xff0c;你可以通过创建一个三角网格对象来表示三维模型&#xff0c;这个对象通常由一个顶点数组和一个索引数组构成。顶点数组包含了模型的各个顶点的…

Linux 进程信号【信号产生】

&#x1f493;博主CSDN主页:麻辣韭菜&#x1f493;   ⏩专栏分类&#xff1a;Linux知识分享⏪   &#x1f69a;代码仓库:Linux代码练习&#x1f69a;   &#x1f339;关注我&#x1faf5;带你学习更多Linux知识   &#x1f51d; 目录 前言 信号概念 1. 生活角度的信号 2…

Java入门基础学习笔记1——初识java

1、为什么学习java&#xff1f; 几乎统治了服务端的开发&#xff1b;几乎所有的互联网企业都使用&#xff1b;100%国内大中型企业都用&#xff1b;全球100亿的设备运行java。开发岗位薪资高。 Java的流行度很高&#xff0c;商用占有率很高。 可移植性。 2、Java的背景知识 …

手机录屏怎么录?简单易懂的教程,让你轻松上手!

随着科技的不断发展&#xff0c;手机录屏已经成为人们日常生活中一个非常普遍的需求。无论是录制游戏精彩瞬间、分享App使用教程&#xff0c;还是保存线上会议、录制网课&#xff0c;手机录屏都发挥着重要作用。可是你知道手机录屏怎么录吗&#xff1f;本文将详细介绍三种手机录…

复现论文的conda环境

前提&#xff1a;已经安装好anaconda 一、使用requirement.txt &#xff08;1&#xff09;查看环境 conda env list &#xff08;2&#xff09;新建环境 之后使用查看环境命令看是否创建成功&#xff0c;创建时等终端收集好数据后要按个y回车 python版本可以在requiremen…

2023年全国职业院校技能大赛网络系统管理网络模块 SDN解题步骤

(六)SDN网络配置 1.考试现场提供SDN控制器登陆的用户名密码信息。 2.S6完成基础IP、VLAN及端口配置确保传统网络连通的情况,使用openflow1.3版本对接至SDN控制器下发策略(基于传统表项转发)达到流量转发控制的目的。 3.SDN控制器下发流表至S6默认禁止所有流量通过。 4…

【漏洞复现】RuvarOA协同办公平台 WorkFlow接口处存在SQL注入

免责声明&#xff1a;文章来源互联网收集整理&#xff0c;请勿利用文章内的相关技术从事非法测试&#xff0c;由于传播、利用此文所提供的信息或者工具而造成的任何直接或者间接的后果及损失&#xff0c;均由使用者本人负责&#xff0c;所产生的一切不良后果与文章作者无关。该…

亲测有效!关键点检测——COCO格式转YOLO格式代码!!!

话不多收&#xff0c;直接上代码&#xff0c;这个我也是找了好久的&#xff0c;分享不易&#xff0c;给个鼓励&#xff01;&#xff08;记得点赞收藏&#xff09; 大家可以直接使用此代码转换你自己的数据集&#xff0c;路径换成你自己的就行了&#xff0c;注意路径格式&#x…

【https】怎么免费实现https!

一、简介 实现 HTTPS&#xff08;Hyper Text Transfer Protocol Secure&#xff09;通常需要购买和配置 SSL/TLS 证书&#xff0c;这是确保网站或应用程序安全传输数据的关键步骤。然而&#xff0c;有一些方法可以在某些情况下“免费”地实现 HTTPS&#xff0c;但这通常涉及到…

React - Input框绑定动态State和监听onChange事件,输入时失去焦点

React - Input框绑定动态State和监听onChange事件&#xff0c;输入时失去焦点 一. 案例复现二. 解决方案 一. 案例复现 案例代码如下&#xff1a; import React, { useState } from react; import { Table, Input } from antd; const Column Table.Column; const mockData …

linux打包流程

因为linux有俩个python版本&#xff0c;我们需要切换到python3这个版本&#xff0c;默认是python 2.7 alias pythonpython3 切换到python3 再次执行&#xff1a;python -V 显示出python的版本了&#xff0c;然后查看pip的配置&#xff0c;我们打包里面需要的第三方需要放到pip…

C#面:简述 类(class)与结构(struct)的异同

类和结构是两种不同的数据类型。 都是用于封装数据和行为的数据类型&#xff0c;但它们在内存分配、继承、赋值和访问方式等方面有一些重要的区别。 相同&#xff1a; 类和结构都是用户自定义的数据类型&#xff0c;用于封装数据和行为。类和结构都可以包含字段、属性、方法…