【前端】深入浅出的React.js详解

React 是一个用于构建用户界面的 JavaScript 库,由 Facebook 开发并维护。随着 React 的不断演进,官方文档也在不断更新和完善。本文将详细解读最新的 React 官方文档,涵盖核心概念、新特性、最佳实践等内容,帮助开发者更好地理解和使用 React。
在这里插入图片描述

1. React 核心概念
1.1 组件

组件是 React 应用的基本构建块。组件可以是类组件或函数组件,每个组件负责渲染一部分用户界面。

1.1.1 函数组件

函数组件是最简单的组件形式,接受输入(props)并返回 JSX。

function Welcome(props) {return <h1>Hello, {props.name}</h1>;
}
1.1.2 类组件

类组件是通过继承 React.Component 类来定义的,可以包含状态和生命周期方法。

class Welcome extends React.Component {render() {return <h1>Hello, {this.props.name}</h1>;}
}
1.2 JSX

JSX 是一种在 JavaScript 中编写类似 HTML 代码的语法扩展。React 使用 JSX 来描述 UI 的结构。

const element = <h1>Hello, world!</h1>;
1.3 Props

Props 是组件之间传递数据的方式。父组件通过 props 将数据传递给子组件。

function Welcome(props) {return <h1>Hello, {props.name}</h1>;
}const element = <Welcome name="Sara" />;
1.4 State

State 是组件内部的数据存储,用于跟踪组件的状态变化。状态的变化会触发组件的重新渲染。

1.4.1 类组件中的状态

在类组件中,状态通过 state 属性来管理。

class Counter extends React.Component {constructor(props) {super(props);this.state = { count: 0 };}increment = () => {this.setState(prevState => ({ count: prevState.count + 1 }));};render() {return (<div><p>Count: {this.state.count}</p><button onClick={this.increment}>Increment</button></div>);}
}
1.4.2 函数组件中的状态

在函数组件中,使用 useState 钩子来管理状态。

import React, { useState } from 'react';function Counter() {const [count, setCount] = useState(0);const increment = () => {setCount(count + 1);};return (<div><p>Count: {count}</p><button onClick={increment}>Increment</button></div>);
}
2. 新特性
2.1 Concurrent Mode

Concurrent Mode 是 React 的一个实验性功能,旨在提高应用的响应性和性能。Concurrent Mode 允许 React 在后台执行工作,并在必要时中断和恢复这些工作。

2.1.1 Suspense

Suspense 是 Concurrent Mode 的一个重要特性,用于处理异步数据加载。通过 Suspense 组件,可以在数据加载完成之前显示一个加载指示器。

import React, { Suspense } from 'react';
import { fetchData } from './api';function DataFetcher() {const data = useDataLoader();return <p>Data: {data}</p>;
}function App() {return (<Suspense fallback={<p>Loading...</p>}><DataFetcher /></Suspense>);
}function useDataLoader() {const [data, setData] = useState(null);useEffect(() => {fetchData().then(data => setData(data));}, []);if (!data) {throw new Promise(resolve => setTimeout(resolve, 1000));}return data;
}
2.2 Hooks

Hooks 是 React 16.8 引入的新特性,允许在函数组件中使用状态和其他 React 特性。

2.2.1 useState

useState 钩子用于在函数组件中添加状态。

import React, { useState } from 'react';function Counter() {const [count, setCount] = useState(0);const increment = () => {setCount(count + 1);};return (<div><p>Count: {count}</p><button onClick={increment}>Increment</button></div>);
}
2.2.2 useEffect

useEffect 钩子用于在函数组件中执行副作用操作,如发起网络请求、设置定时器等。

import React, { useState, useEffect } from 'react';function DataFetcher() {const [data, setData] = useState(null);useEffect(() => {fetch('https://api.example.com/data').then(response => response.json()).then(data => setData(data));}, []);return (<div>{data ? (<p>Data: {data}</p>) : (<p>Loading...</p>)}</div>);
}
2.2.3 useContext

useContext 钩子用于在函数组件中使用 Context。

import React, { createContext, useContext } from 'react';const ThemeContext = createContext('light');function ThemedButton() {const theme = useContext(ThemeContext);return <button style={{ background: theme }}>Button</button>;
}function App() {return (<ThemeContext.Provider value="dark"><ThemedButton /></ThemeContext.Provider>);
}
3. 生命周期方法

生命周期方法是类组件中的一系列方法,用于在组件的不同阶段执行特定的操作。函数组件中使用钩子来实现类似的功能。

3.1 类组件中的生命周期方法
3.1.1 componentDidMount

在组件挂载后立即调用,通常用于发起网络请求或设置定时器。

class DataFetcher extends React.Component {state = {data: null};componentDidMount() {fetch('https://api.example.com/data').then(response => response.json()).then(data => this.setState({ data }));}render() {return (<div>{this.state.data ? (<p>Data: {this.state.data}</p>) : (<p>Loading...</p>)}</div>);}
}
3.1.2 componentDidUpdate

在组件更新后立即调用,可以用于比较新旧状态或属性,执行相应的操作。

class DataFetcher extends React.Component {state = {data: null,id: 1};componentDidUpdate(prevProps, prevState) {if (prevState.id !== this.state.id) {fetch(`https://api.example.com/data/${this.state.id}`).then(response => response.json()).then(data => this.setState({ data }));}}changeId = () => {this.setState(prevState => ({ id: prevState.id + 1 }));};render() {return (<div>{this.state.data ? (<p>Data: {this.state.data}</p>) : (<p>Loading...</p>)}<button onClick={this.changeId}>Change ID</button></div>);}
}
3.1.3 componentWillUnmount

在组件卸载前调用,通常用于清理定时器或取消网络请求。

class Timer extends React.Component {state = {seconds: 0};interval = null;componentDidMount() {this.interval = setInterval(() => {this.setState(prevState => ({ seconds: prevState.seconds + 1 }));}, 1000);}componentWillUnmount() {clearInterval(this.interval);}render() {return <p>Seconds: {this.state.seconds}</p>;}
}
3.2 函数组件中的生命周期方法
3.2.1 useEffect

useEffect 钩子用于在函数组件中执行副作用操作,如发起网络请求、设置定时器等。

3.2.1.1 模拟 componentDidMount

在组件挂载后执行操作:

import React, { useState, useEffect } from 'react';function DataFetcher() {const [data, setData] = useState(null);useEffect(() => {fetch('https://api.example.com/data').then(response => response.json()).then(data => setData(data));}, []); // 空数组表示只在组件挂载时执行一次return (<div>{data ? (<p>Data: {data}</p>) : (<p>Loading...</p>)}</div>);
}
3.2.1.2 模拟 componentDidUpdate

在组件更新后执行操作:

import React, { useState, useEffect } from 'react';function DataFetcher() {const [data, setData] = useState(null);const [id, setId] = useState(1);useEffect(() => {fetch(`https://api.example.com/data/${id}`).then(response => response.json()).then(data => setData(data));}, [id]); // 依赖数组包含 id,表示当 id 变化时重新执行const changeId = () => {setId(id + 1);};return (<div>{data ? (<p>Data: {data}</p>) : (<p>Loading...</p>)}<button onClick={changeId}>Change ID</button></div>);
}
3.2.1.3 模拟 componentWillUnmount

在组件卸载前执行清理操作:

import React, { useState, useEffect } from 'react';function Timer() {const [seconds, setSeconds] = useState(0);useEffect(() => {const interval = setInterval(() => {setSeconds(prevSeconds => prevSeconds + 1);}, 1000);return () => clearInterval(interval); // 清理定时器}, []); // 空数组表示只在组件挂载时执行一次return <p>Seconds: {seconds}</p>;
}
4. 最佳实践
4.1 代码分割和懒加载

通过代码分割和懒加载,可以优化应用的初始加载时间和性能。

import React, { Suspense, lazy } from 'react';const OtherComponent = lazy(() => import('./OtherComponent'));function App() {return (<div><Suspense fallback={<div>Loading...</div>}><OtherComponent /></Suspense></div>);
}
4.2 避免不必要的渲染

通过 React.memoPureComponent,可以避免不必要的组件重新渲染。

4.2.1 React.memo

React.memo 是一个高阶组件,用于优化函数组件的性能。

import React from 'react';const MyComponent = React.memo(function MyComponent(props) {/* 只在 props 发生变化时重新渲染 */return <div>{props.value}</div>;
});
4.2.2 PureComponent

PureComponent 是一个基类,用于优化类组件的性能。

import React from 'react';class MyComponent extends React.PureComponent {render() {/* 只在 props 或 state 发生变化时重新渲染 */return <div>{this.props.value}</div>;}
}
4.3 使用 useMemouseCallback

useMemouseCallback 钩子可以用于优化性能,避免不必要的计算和函数创建。

4.3.1 useMemo

useMemo 用于缓存计算结果,避免不必要的计算。

import React, { useMemo } from 'react';function MyComponent({ list }) {const sortedList = useMemo(() => list.sort(), [list]);return <div>{sortedList.join(', ')}</div>;
}
4.3.2 useCallback

useCallback 用于缓存函数,避免不必要的函数创建。

import React, { useCallback } from 'react';function MyComponent({ onIncrement }) {const handleIncrement = useCallback(() => {onIncrement();}, [onIncrement]);return <button onClick={handleIncrement}>Increment</button>;
}
4.4 错误边界

错误边界是一种 React 组件,可以捕获并处理其子组件树中抛出的 JavaScript 错误。

class ErrorBoundary extends React.Component {constructor(props) {super(props);this.state = { hasError: false };}static getDerivedStateFromError(error) {return { hasError: true };}componentDidCatch(error, errorInfo) {logErrorToMyService(error, errorInfo);}render() {if (this.state.hasError) {return <h1>Something went wrong.</h1>;}return this.props.children;}
}function App() {return (<ErrorBoundary><MyWidget /></ErrorBoundary>);
}
5. 示例代码

以下是一些综合示例,展示了如何在 React 中使用不同的特性和最佳实践。

5.1 类组件示例
class DataFetcher extends React.Component {state = {data: null,id: 1};componentDidMount() {this.fetchData();}componentDidUpdate(prevProps, prevState) {if (prevState.id !== this.state.id) {this.fetchData();}}componentWillUnmount() {this.abortController.abort();}fetchData = () => {this.abortController = new AbortController();fetch(`https://api.example.com/data/${this.state.id}`, { signal: this.abortController.signal }).then(response => response.json()).then(data => this.setState({ data })).catch(error => console.error('Fetch error:', error));};changeId = () => {this.setState(prevState => ({ id: prevState.id + 1 }));};render() {return (<div>{this.state.data ? (<p>Data: {this.state.data}</p>) : (<p>Loading...</p>)}<button onClick={this.changeId}>Change ID</button></div>);}
}
5.2 函数组件示例
import React, { useState, useEffect, useCallback } from 'react';function DataFetcher() {const [data, setData] = useState(null);const [id, setId] = useState(1);useEffect(() => {const abortController = new AbortController();fetch(`https://api.example.com/data/${id}`, { signal: abortController.signal }).then(response => response.json()).then(data => setData(data)).catch(error => console.error('Fetch error:', error));return () => abortController.abort(); // 清理请求}, [id]);const changeId = useCallback(() => {setId(id + 1);}, [id]);return (<div>{data ? (<p>Data: {data}</p>) : (<p>Loading...</p>)}<button onClick={changeId}>Change ID</button></div>);
}
6. 总结

React 是一个强大的库,用于构建用户界面。通过理解核心概念、新特性和最佳实践,开发者可以更高效地使用 React 构建高性能和响应式的应用。本文详细解读了最新的 React 官方文档,涵盖了组件、JSX、Props、State、生命周期方法、Hooks、Concurrent Mode 等内容,并提供了示例代码和最佳实践。

附录

  • React 官方文档:React 文档
  • React Hooks 文档:React Hooks
  • MDN Web 文档:React 简介

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

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

相关文章

【Elasticsearch入门到落地】1、初识Elasticsearch

一、什么是Elasticsearch Elasticsearch&#xff08;简称ES&#xff09;是一款非常强大的开源搜索引擎&#xff0c;可以帮助我们从海量数据中快速找到需要的内容。它使用Java编写&#xff0c;基于Apache Lucene来构建索引和提供搜索功能&#xff0c;是一个分布式、可扩展、近实…

扫雷游戏代码分享(c基础)

hi , I am 36. 代码来之不易&#x1f44d;&#x1f44d;&#x1f44d; 创建两个.c 一个.h 1&#xff1a;test.c #include"game.h"void game() {//创建数组char mine[ROWS][COLS] { 0 };char show[ROWS][COLS] { 0 };char temp[ROWS][COLS] { 0 };//初始化数…

ORA-01092 ORA-14695 ORA-38301

文章目录 前言一、MAX_STRING_SIZE--12C 新特性扩展数据类型 varchar2(32767)二、恢复操作1.尝试恢复MAX_STRING_SIZE参数为默认值2.在upgrade模式下执行utl32k.sql 前言 今天客户发来一个内部测试库数据库启动截图报错&#xff0c;描述是“上午出现服务卡顿&#xff0c;然后重…

ODOO学习笔记(3):Odoo和Django的区别是什么?

Odoo和Django都是基于Python的开源框架&#xff0c;但它们的设计目标和用途有所不同&#xff1a; 设计目标和用途&#xff1a; Odoo&#xff1a;Odoo是一个企业资源规划&#xff08;ERP&#xff09;系统&#xff0c;它提供了一套完整的商业管理软件&#xff0c;包括会计、库存…

零基础玩转IPC之——海思平台实现P2P远程传输实验(基于TUTK,国科君正全志海思通用)

老规矩&#xff0c;先做实验测试。以本店Hi3516EV200\GK7205开发板为例&#xff0c;其他开发板操作类似。 将源码包p2p-h264.tgz放到虚拟机&#xff0c;解压&#xff0c;编译 tar -jxvf p2p-h264.tgz cd p2p-h264 make clean make 得到可执行文件p2p-h264 启动开发板&…

如何理解DDoS安全防护在企业安全防护中的作用

DDoS安全防护在安全防护中扮演着非常重要的角色。DDoS&#xff08;分布式拒绝服务&#xff09;攻击是一种常见的网络攻击&#xff0c;旨在通过向目标服务器发送大量请求&#xff0c;以消耗服务器资源并使其无法正常运行。理解DDoS安全防护的作用&#xff0c;可以从以下几个方面…

Python如何从HTML提取img标签下的src属性

目录 前提准备步骤1. 解析HTML内容2. 查找所有的img标签3. 提取src属性 完整代码 前提准备 在处理网页数据时&#xff0c;我们经常需要从HTML中提取特定的信息&#xff0c;比如图片的URL。 这通常通过获取img标签的src属性来实现。 在开始之前&#xff0c;你需要确保已经安装…

Redis主从复制(replication)

文章目录 是什么作用使用案例实操主从复制原理和工作流程slave启动&#xff0c;同步初请首次连接&#xff0c;全量复制心跳持续&#xff0c;保持通信进入平稳&#xff0c;增量复制从机下线&#xff0c;重连续传 复制的缺点 是什么 主从复制&#xff0c;master以写为主&#xf…

Android OpenGL ES详解——纹理:纹理过滤GL_NEAREST和GL_LINEAR的区别

目录 一、概念 1、纹理过滤 2、邻近过滤 3、线性过滤 二、邻近过滤和线性过滤的区别 三、源码下载 一、概念 1、纹理过滤 当纹理被应用到三维物体上时&#xff0c;随着物体表面的形状和相机视角的变化&#xff0c;会导致纹理在渲染过程中出现一些问题&#xff0c;如锯齿…

记录日志中logback和log4j2不能共存的问题

本文章记录设置两个日志时候&#xff0c;控制台直接报错 标黄处就是错误原因&#xff1a;1. SLF4J(W)&#xff1a;类路径包含多个SLF4J提供程序。 SLF4J(W)&#xff1a;找到提供程序[org.apache.logging.slf4j. net]。 SLF4J(W)&#xff1a;找到提供程序[ch.qos.log .classi…

【PGCCC】Postgresql Toast 原理

前言 上篇博客讲述了 postgresql 如何存储变长数据&#xff0c;它的应用主要是在 toast 。Toast 在存储大型数据时&#xff0c;会将它存储在单独的表中&#xff08;称为 toast 表&#xff09;。因为 postgresql 的 tuple&#xff08;行数据&#xff09;是存在在 Page 中的&…

C指针创建三维数组

定义的时候变量的位置就是最后一个星号的位置 int*** matrix3d_int(int nz, int nrh, int nch) {int*** matrix (int***)malloc(nz * sizeof(int**));for (int z 0; z < nz; z) {matrix[z] (int**)malloc(nrh * sizeof(int*));for (int y 0; y < nrh; y) {matrix[z][…

window下安装rust 及 vscode配置

安装 安装mingw64 &#xff08;c语言环境 选择posix-ucrt&#xff09; ucrt:通用c运行时库配置mingw64/bin的路径到环境变量中在cmd窗口中输入命令 "gcc -v" 4. 下载Rust安装程序 安装 Rust - Rust 程序设计语言 5. 配置rustup和cargo目录 &#xff08;cargo是包管…

wordpress搭建主题可配置json

网站首页展示 在线访问链接 http://dahua.bloggo.chat/ 配置json文件 我使用的是argon主题&#xff0c;你需要先安装好主题&#xff0c;然后可以导入我的json文件一键配置。 需要json界面配置文件的&#xff0c;可以在评论区回复&#xff0c;看见评论我会私发给你。~

基于表格滚动截屏(表格全部展开,没有滚动条)

import html2canvasPro from html2canvas // 截图&#xff0c;平辅表格 async function resetAgSize() {const allColumns gridApi.value.getColumns()let totalColumnWidth 0let totalColumnHeight 0// 遍历每一个行节点gridApi.value.forEachNode((rowNode) > {totalCo…

运行springBlade项目历程

框架选择 官网地址&#xff1a;https://bladex.cn 使用手册&#xff1a;https://www.kancloud.cn/smallchill/blade 常见问题&#xff1a;https://sns.bladex.cn/article-14966.html 问答社区&#xff1a;https://sns.bladex.cn 环境配置 存在jdk8的情况下安装jdk17 jdk17gi…

文件上传漏洞--理论

什么是文件上传漏洞&#xff1f; Web应用允许用户上传文件&#xff0c;但是没有对上传的文件进行严格的过滤和检测&#xff0c;导致网站执行了文件中包含的恶意代码。 漏洞的基本利用方式是&#xff1a; 成功上传包含恶意代码的文件&#xff0c;并在服务端成功执行该文件。 …

物联网(RFID)全景:被装信息化监控应用与挑战

一、被装物联网信息化建设的动因 信息化改革在20世纪80年代中期启航&#xff0c;旨在提升被装保障的效率。随着时间的推移&#xff0c;硬件的广泛运用和软件的快速迭代&#xff0c;装备业务在规划、制造、分发以及战时支援等核心环节&#xff0c;已经与信息系统深度融合&#x…

解决C盘空间不足的三种方案

方案一&#xff1a;网上盛传的C盘磁盘碎片整理&#x1f9e9;&#xff08;原理&#xff1a;将分散的文件片段整理到相邻的磁盘区域&#xff0c;减少文件的碎片化程度&#xff09;(效果不明显) 方案二&#xff1a;把其他盘的空间给C盘 &#x1f4bd;&#xff08;效果显著&#xf…

[项目代码] YOLOv5 铁路工人安全帽安全背心识别 [目标检测]

YOLOv5是一种单阶段&#xff08;one-stage&#xff09;检测算法&#xff0c;它将目标检测问题转化为一个回归问题&#xff0c;能够在一次前向传播过程中同时完成目标的分类和定位任务。相较于两阶段检测算法&#xff08;如Faster R-CNN&#xff09;&#xff0c;YOLOv5具有更高的…