React复习

文章目录

    • 常用的Hooks
      • useState
      • useReducer
      • useRef
      • useContext
      • useMemo
      • useCallback
      • useEffect
    • 组件通信
      • Props(属性)
      • Ref(引用)
      • Context(上下文)
      • State(状态)
      • 回调函数
      • Event Bus(事件总线)
      • Custom Hooks(自定义钩子)
      • Redux
    • 生命周期
      • React 17 之前:
      • React 17 之后:
      • 常用的生命周期方法:
        • Class 组件中常用:
        • Function 组件中使用(Hooks):
      • 不常用的生命周期方法:
        • Class 组件中不常用:
        • Class 组件中特有的:

好多年没使react了,有些忘了,简单复习一下…

常用的Hooks

useState

用于管理组件内部的状态,允许在函数组件中添加和管理 state。

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

useReducer

管理复杂的状态逻辑,特别是当 state 逻辑涉及到多个子值,或者下一个 state 依赖于前一个 state 时。

import React, { useReducer } from 'react';const initialState = { count: 0 };
function reducer(state, action) {switch (action.type) {case 'increment':return { count: state.count + 1 };case 'decrement':return { count: state.count - 1 };default:return state;}
}function Counter() {const [state, dispatch] = useReducer(reducer, initialState);return (<>Count: {state.count}<button onClick={() => dispatch({ type: 'decrement' })}>-</button><button onClick={() => dispatch({ type: 'increment' })}>+</button></>);
}

useRef

在组件中直接访问DOM 元素;

import React, { useRef } from 'react';function TextInputWithFocusButton() {const inputEl = useRef(null);const onButtonClick = () => {// `current` 指向挂载的文本输入元素inputEl.current.focus();};return (<><input ref={inputEl} type="text" /><button onClick={onButtonClick}>Focus the input</button></>);
}

在组件的不同渲染之间保持一个可变的值,并且这个值不会触发组件的重新渲染。

import React, { useRef, useState, useEffect } from 'react';function Timer() {const intervalRef = useRef();const [count, setCount] = useState(0);useEffect(() => {intervalRef.current = setInterval(() => {setCount((c) => c + 1);}, 1000);return () => clearInterval(intervalRef.current);}, []);return (<div><p>Count: {count}</p><button onClick={() => clearInterval(intervalRef.current)}>Stop Timer</button></div>);
}

useContext

在组件之间共享状态,而不必通过 “props下钻” 层层传递。

import React, { useContext } from 'react';
const ThemeContext = React.createContext('light');function ThemedButton() {const theme = useContext(ThemeContext);return <button theme={theme}>I am styled by theme context!</button>;
}

useMemo

缓存计算密集型函数的返回值。
当你把一些计算开销较大的值或者组件作为依赖项传递给其他组件或者渲染逻辑时,使用 useMemo 可以避免不必要的计算,从而提高性能。

import React, { useMemo } from 'react';function expensiveCalculation(num) {console.log('Calculating...');for (let i = 0; i < 1000000; i++) {} // 模拟一个耗时计算return num * 2;
}function MyComponent({ a, b }) {const memoizedValue = useMemo(() => {return expensiveCalculation(a);}, [a]); // 只有 a 改变时,才会重新计算return (<div>{memoizedValue}<p>Dependency: {b}</p></div>);
}

useCallback

缓存函数。
当你将一个函数传递给子组件或者作为 props 传递时,使用 useCallback 可以避免不必要的渲染,从而提高性能。

import React, { useCallback, useState } from 'react';function MyComponent() {const [count, setCount] = useState(0);const handleIncrement = useCallback(() => {setCount((c) => c + 1);}, []); // 由于 setCount 是稳定的,所以这里不需要依赖项const handleDecrement = useCallback(() => {setCount((c) => c - 1);}, []); // 同上return (<div><button onClick={handleIncrement}>Increment</button><button onClick={handleDecrement}>Decrement</button><p>Count: {count}</p></div>);
}

useEffect

允许在函数组件中执行副作用操作,如数据获取、订阅或手动更改 React 组件中的 DOM。

import React, { useState, useEffect } from 'react';function ExampleComponent() {useEffect(() => {// 这个函数会在组件每次渲染后执行// 可以在这里执行副作用操作return () => {// 这个清理函数会在组件卸载前执行};}, []); // 空数组表示这个 effect 只会在组件挂载时执行一次return <div>Hello, world!</div>;
}

组件通信

Props(属性)

最常见的方式是通过props属性将数据从父组件传递给子组件。父组件可以在子组件的标签中传递props,子组件通过props接收数据。

// ParentComponent.js
import ChildComponent from './ChildComponent';function ParentComponent() {const data = 'Hello from parent';return <ChildComponent data={data} />;
}// ChildComponent.js
function ChildComponent(props) {return <div>{props.data}</div>;
}

Ref(引用)

可以使用ref来直接访问子组件的实例,并通过实例方法传递数据。

// ParentComponent.js
import React, { useRef } from 'react';
import ChildComponent from './ChildComponent';function ParentComponent() {const childRef = useRef();const sendDataToChild = () => {childRef.current.handleData('Hello from parent');};return (<><ChildComponent ref={childRef} /><button onClick={sendDataToChild}>Send Data</button></>);
}// ChildComponent.js
import React, { forwardRef, useImperativeHandle } from 'react';const ChildComponent = forwardRef((props, ref) => {const handleData = (data) => {console.log(data);};useImperativeHandle(ref, () => ({handleData}));return <div>Child Component</div>;
});export default ChildComponent;

Context(上下文)

Context允许在组件树中传递数据,而不必一级一级手动传递props。适用于跨多层级的组件传递数据。

// DataContext.js
import React from 'react';const DataContext = React.createContext();export default DataContext;// ParentComponent.js
import DataContext from './DataContext';
import ChildComponent from './ChildComponent';function ParentComponent() {const data = 'Hello from parent';return (<DataContext.Provider value={data}><ChildComponent /></DataContext.Provider>);
}// ChildComponent.js
import DataContext from './DataContext';function ChildComponent() {return (<DataContext.Consumer>{data => <div>{data}</div>}</DataContext.Consumer>);
}

State(状态)

通过组件的状态来传递数据。父组件可以将数据存储在自身的状态中,然后通过props将数据传递给子组件。

// ParentComponent.js
import ChildComponent from './ChildComponent';function ParentComponent() {const [data, setData] = useState('Hello from parent');return <ChildComponent data={data} />;
}// ChildComponent.js
function ChildComponent(props) {return <div>{props.data}</div>;
}

回调函数

父组件可以通过回调函数将数据传递给子组件。子组件可以调用回调函数来传递数据给父组件。

// ParentComponent.js
import ChildComponent from './ChildComponent';function ParentComponent() {const handleData = (data) => {console.log(data);};return <ChildComponent sendData={handleData} />;
}// ChildComponent.js
function ChildComponent(props) {const sendDataToParent = () => {props.sendData('Hello from child');};return <button onClick={sendDataToParent}>Send Data</button>;
}

Event Bus(事件总线)

通过事件总线来进行组件间的通信,一个组件发送事件,另一个组件监听事件并做出相应处理。

// EventBus.js
import { EventEmitter } from 'events';const eventBus = new EventEmitter();export default eventBus;// ParentComponent.js
import eventBus from './EventBus';
import ChildComponent from './ChildComponent';function ParentComponent() {const sendDataToChild = () => {eventBus.emit('sendData', 'Hello from parent');};return (<><ChildComponent /><button onClick={sendDataToChild}>Send Data</button></>);
}// ChildComponent.js
import React, { useEffect } from 'react';
import eventBus from './EventBus';function ChildComponent() {useEffect(() => {eventBus.on('sendData', (data) => {console.log(data);});return () => {eventBus.off('sendData');};}, []);return <div>Child Component</div>;
}

Custom Hooks(自定义钩子)

通过自定义钩子来共享逻辑和状态,并在不同组件中使用。可以将数据存储在自定义钩子中,然后在需要的组件中使用。

// UseData.js
import { useState } from 'react';const useData = () => {const [data, setData] = useState('Hello from custom hook');return { data, setData };
};export default useData;// ParentComponent.js
import useData from './UseData';
import ChildComponent from './ChildComponent';function ParentComponent() {const { data } = useData();return <ChildComponent data={data} />;
}// ChildComponent.js
function ChildComponent(props) {return <div>{props.data}</div>;
}

Redux

在React中结合Redux进行状态管理,通常需要使用react-redux库来连接Redux Store和React组件。

  • 创建Redux Store:
// store.js
import { createStore } from 'redux';
import rootReducer from './reducers';const store = createStore(rootReducer);export default store;
  • 定义Reducer:
// reducers.js
const initialState = {count: 0
};const counterReducer = (state = initialState, action) => {switch (action.type) {case 'INCREMENT':return { ...state, count: state.count + 1 };case 'DECREMENT':return { ...state, count: state.count - 1 };default:return state;}
};export default counterReducer;
  • 连接Redux Store和React组件:
// App.js
import React from 'react';
import { useSelector, useDispatch } from 'react-redux';const App = () => {const count = useSelector(state => state.count);const dispatch = useDispatch();const increment = () => {dispatch({ type: 'INCREMENT' });};const decrement = () => {dispatch({ type: 'DECREMENT' });};return (<div><h1>Count: {count}</h1><button onClick={increment}>Increment</button><button onClick={decrement}>Decrement</button></div>);
};export default App;
  • Provider组件:在根组件中使用Provider组件将Redux Store传递给整个应用程序。
// index.js
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import store from './store';
import App from './App';ReactDOM.render(<Provider store={store}><App /></Provider>,document.getElementById('root')
);

状态管理还有很多其他的方式(特别卷)。比如: Zustand、MobX等等


生命周期

挂载(Mounting)、更新(Updating)和卸载(Unmounting)的过程。

React 17 之前:

挂载阶段(Mounting)

  • constructor(): 构造函数,在组件被创建时调用,用于初始化state、可以接收一个父组件传来的props、绑定事件处理方法。
  • componentWillMount(已弃用): 组件将要挂载
  • render(): 在这里面我们会写一些html标签及自定义的函数,render执行完后便会将这些语句对应渲染到浏览器上面。
  • componentDidMount(): 组件挂载后调用,通常用于进行异步数据获取、订阅事件等操作。

更新阶段(Updating)

  • componentWillReceiveProps(已弃用): 在组件接收到新的 props 之前调用。
  • shouldComponentUpdate(): 决定是否重新渲染组件,在接收新props或state时调用,用于性能优化。 当更新state值的时候会执行这个函数,比如this.setState({})。
  • componentWillUpdate(已弃用): 会在组件接收到新的 props 或 state 并即将重新渲染之前被调用。
  • render(): 和初始化时候执行的那个render一样,只是这里是更新值的,所以dom节点会重新更新一下。
  • componentDidUpdate(): 组件更新后调用,通常用于处理DOM操作、网络请求等。

卸载阶段(Unmounting)

  • componentWillUnmount(): 组件卸载前调用,用于清理定时器、取消订阅等操作。

React 17 之后:

挂载阶段(Mounting)

  • constructor()
  • static getDerivedStateFromProps: React 会在初始挂载和后续更新时调用 render 之前调用它。它应该返回一个对象来更新 state,或者返回 null 就不更新任何内容。挂载阶段只调用一次,用于初始化 state。
  • render()
  • componentDidMount()

更新阶段(Updating)

  • static getDerivedStateFromProps: 更新阶段每次组件接收到新的 props 时都会被调用。
  • shouldComponentUpdate()
  • render()
  • getSnapshotBeforeUpdate: 会在 React 更新 DOM 之前时直接调用它。它使你的组件能够在 DOM 发生更改之前捕获一些信息(例如滚动的位置)。此生命周期方法返回的任何值都将作为参数传递给 componentDidUpdate。
  • componentDidUpdate()

卸载阶段(Unmounting)

  • componentWillUnmount()

在这里插入图片描述

除了上述生命周期方法,还有componentDidCatch()用于捕获组件树中的错误。此外,React Hooks也提供了函数式组件中的生命周期替代方案,如useEffect()用于处理副作用。

  • componentDidCatch:
import React, { Component } from 'react';class ErrorBoundary extends Component {constructor(props) {super(props);this.state = { hasError: false };}componentDidCatch(error, info) {this.setState({ hasError: true });console.error('Error caught by ErrorBoundary:', error, info);}render() {if (this.state.hasError) {return <h1>Something went wrong.</h1>;}return this.props.children;}
}export default ErrorBoundary;
  • useEffect: 在函数式组件中,可以使用React Hooks来替代类组件中的生命周期方法。
import { useState, useEffect } from 'react';const FunctionalComponent = () => {const [count, setCount] = useState(0);// 相当于 componentDidMount 和 componentDidUpdateuseEffect(() => {console.log('Component is mounted or updated');// 清理函数,相当于 componentWillUnmountreturn () => {console.log('Component is about to unmount');};}, [count]); // 仅在count发生变化时触发// 模拟 shouldComponentUpdateconst shouldUpdate = (nextProps, nextState) => {if (nextState.count !== count) {return true;}return false;};const handleClick = () => {setCount(count + 1);};return (<div><p>Count: {count}</p><button onClick={handleClick}>Increment Count</button></div>);
};export default FunctionalComponent;

常用的生命周期方法:

在这里插入图片描述

Class 组件中常用:
  • constructor(): 用于初始化 state 和绑定方法。
  • render(): 必须的方法,用于渲染组件。
  • componentDidMount(): 在组件挂载后被调用,常用于进行 API 调用、订阅等。
  • componentDidUpdate(prevProps, prevState): 在组件更新后被调用,可以用于比较 props 和 state 的变化。
  • componentWillUnmount(): 在组件卸载前被调用,常用于清理资源,如取消订阅、清除定时器等。
Function 组件中使用(Hooks):
  • useEffect(): 用于在函数组件中执行副作用操作,类似于 componentDidMount、componentDidUpdate 和 componentWillUnmount。
  • useLayoutEffect(): 类似于 useEffect,但它会在所有的 DOM 变更之后同步调用 effect,适用于读取 DOM 布局并同步触发重渲染的情况。

不常用的生命周期方法:

Class 组件中不常用:
  • UNSAFE_componentWillMount(): 虽然可用,但官方不推荐使用,其用途通常可以在 componentDidMount 中实现。
  • UNSAFE_componentWillReceiveProps(nextProps): 虽然可用,但官方不推荐使用,推荐使用 getDerivedStateFromProps 或在 componentDidUpdate 中处理新的 props。
  • UNSAFE_componentWillUpdate(nextProps, nextState): 虽然可用,但官方不推荐使用,其用途通常可以在 componentDidUpdate 中实现。
Class 组件中特有的:
  • getDerivedStateFromProps(props, state): 这是一个静态方法,用于根据 props 更新 state,在组件挂载和更新时都会被调用

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

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

KDTS 实现MySQL至KingbaseES迁移实践

此文章以linux环境实践&#xff0c;KingbaseES一下使用KES代替。 KDTS KDTS工具安装KES时会一起安装&#xff0c;一般存在目录为&#xff1a;ClientTools目录下guitools文件夹中 启动 进入KDTS-WEB下bin目录&#xff0c;执行sh文件 cd /opt/Kingbase/ES/V8/ClientTools/guit…

盘点2024年15大投屏软件电脑版,看看哪款最好用?

无线投屏软件哪个好用&#xff0c;相信这个问题困扰过不少同鞋&#xff0c;最重要的当然是画质高、投屏流畅&#xff0c;最好还是免费滴&#xff01; 接下来就分享下国内外一些流行的投屏工具&#xff0c;共计15款&#xff0c;通过对比他们的 优缺点&#xff0c;相信你可以快速…

2025西安电子科技大学研招网拟招生人数VS 24年实际录取人数

研招网拟招生人数 VS 24年实际录取人数&#xff08;分析速览&#xff09; 10月8日研招网公布拟招生人数信息后&#xff0c;就有同学问研招网人数准不准确&#xff0c;其实研招网公布的人数并不不准确&#xff0c;但是学长学姐还是给大家统计了一下&#xff0c;与去年实际录取人…

nginx问题解决-nginx代理数据库端口

一.问题背景 无法直接访问数据库地址&#xff0c;需要公网转发访问 二.配置文件 stream {upstream sql_socket {server IP:端口;#sql ip和端口}server {listen 端口;proxy_connect_timeout 60s;proxy_pass sql_socket;} } 三.异常处理 重新编译Nginx并在编译选项中包含--wi…

开源计算器应用的全面测试计划:确保功能性和可靠性

✅作者简介&#xff1a;2022年博客新星 第八。热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;Java Fans的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏…

abc374 g

很容易想到建图&#xff0c;初始想法为&#xff0c;建完图后&#xff0c;求一个最小路径覆盖&#xff0c;但因为整个图不是DAG&#xff0c;所以需要缩点&#xff0c;但路径覆盖有两种说法&#xff0c;一种是最小不相交路径覆盖&#xff0c;另一种是最小可相交路径覆盖。 对于最…

Linux-更多的结构化命令

for命令 C语言风格的for语句 while命令 until命令 嵌套循环 循环处理文件数据 控制循环-break命令 控制循环-continue命令 处理循环输出 实例&#xff1a;查询可执行文件、创建多个用户账户

【华为OD机试真题】95、最少面试官数

package mainimport ("fmt""sort" )type s struct {start intend intworkCount int }type duration struct {start intend int }// 查询时间段内是否有可用的面试官 func getFreeS(sList []*s, d *duration, workCountLimit int) (sIndex int)…

DASCTF 2024暑期挑战赛wp

WEB 题目&#xff1a;Sanics revenge 解题步骤 首先看到给出的附件: from sanic import Sanic import os from sanic.response import text, html import sys import random import pydash # pydash5.1.2 # 这里的源码好像被admin删掉了一些&#xff0c;听他说里面藏有大秘密 c…

两个pdf怎么合并成一个pdf?超简单的合并方法分享

在日常工作和学习中&#xff0c;我们经常会遇到需要将多个PDF文件合并成一个文件的情况&#xff0c;以便更好地管理和分享。今天&#xff0c;将为大家详细介绍5种实用的方法&#xff0c;能够一键合并多个PDF文件&#xff0c;有需要的小伙伴快来一起学习下吧。 方法一&#xff1…

车牌字符识别系统源码分享

车牌字符识别系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vision …

霍普菲尔德(Hopfield)神经网络求解旅行商问题TSP,提供完整MATLAB代码,复制粘贴即可运行

Hopfield神经网络是以美国物理学家约翰霍普菲尔德&#xff08;John Hopfield&#xff09;的名字命名的。他在1982年提出了这种类型的神经网络模型&#xff0c;因此通常被称为Hopfield网络。旅行商问题&#xff08;Traveling Salesman Problem&#xff0c;TSP&#xff09;是一个…

Linux文件权限与用户管理详解:权限、所属用户组和所有者的变更

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐&#xff1a;「storm…

七氟烷麻醉药市场研究:未来几年年复合增长率CAGR为4.2%

七氟烷是一种吸入麻醉剂&#xff0c;用于在外科手术过程中诱导和维持全身麻醉。七氟烷是一种挥发性麻醉剂&#xff0c;常用于在外科手术过程中诱导和维持全身麻醉。它因起效快和作用消失快而受到青睐&#xff0c;是成人和儿科患者的理想选择。七氟烷通常通过吸入起作用&#xf…

考研报名记录冲冲冲

研究生报名 网址 https://yz.chsi.com.cn/apply/ 报名包括网上报名和网上确认两个阶段&#xff0c;所有考生均须在规定时间内参加网上报名和网上确认。网上报名时间为2024年10月15日至10月28日&#xff08;网上预报名时间为2024年10月9日至10月12日&#xff0c;网上预报名和正…

计算机中的BIOS是什么?BIOS设置界面怎么进入?

计算机术语中我们常说的BIOS是基本输入输出系统&#xff08;Basic Input & Output System&#xff09;的简称。它是一组固化在计算机主板上的ROM芯片中的程序&#xff0c;计算机启动时最早运行的软件之一。它保存着计算机最重要的基本输入输出的程序、开机自检程序和系统自…

wordpress使用popup弹窗插件的对比

您在寻找最好的 WordPress 弹出插件吗&#xff1f;大多数网站利用某种形状或形式的弹出窗口来将访问者指向他们希望他们去的地方。例如&#xff0c;这可能用于结帐、电子邮件订阅或用于生成潜在客户。 表现 弹出插件会减慢您的网站速度。当插件使用 WordPress 跟踪弹出窗口的…

SQL注入之报错注入方法汇总

报错注入 什么是报错注入 0.1 定义&#xff1a; 报错注入是通过特殊函数错误使用并使其输出错误结果来获取信息的。是一种页面响应形式。 响应过程&#xff1a; 用户在前台页面输入检索内容后台将前台页面上输入的检索内容无加区别的拼接成sql语句&#xff0c;送给数据库执…

VR科技云展如何以沉浸式体验引领科技成果新展示

一、VR科技云展的展示方式 VR科技云展通过虚拟现实技术&#xff0c;将展厅移植到虚拟空间中&#xff0c;使观众可以通过互联网在线参观展览。这种展示方式打破了时间和空间的限制&#xff0c;观众只需通过电脑、平板、手机等设备&#xff0c;就能随时随地体验展览。 1、沉浸式漫…

压缩图片最简单的方法有哪些?2024帮助你压缩出你需要的文件大小的软件

压缩图片最简单的方法有哪些&#xff1f;2024帮助你压缩出你需要的文件大小的软件 压缩图片可以帮助减少文件大小&#xff0c;从而更方便地进行存储、传输或上传到网站。以下是五款好用的图片压缩软件&#xff0c;它们能够帮助你快速、轻松地压缩图片至所需的文件大小。 万能图…