React的根本API先容(一)

[复制链接]
发表于 2025-12-27 13:54:04 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
useEffect

useEffect 是 React 中的一个 Hook,用于在函数组件中处置惩罚副作用操纵,比方数据获取、订阅变乱、手动修改 DOM 等。以下是 useEffect 的一些告急特性和优点:
1. 替换生命周期方法

模拟类组件的生命周期:useEffect 可以模拟类组件的 componentDidMount、componentDidUpdate 和 componentWillUnmount 方法,答应在组件的差异阶段实行相应的逻辑。
  1. useEffect(() => {
  2.   // componentDidMount 和 componentDidUpdate 的逻辑
  3.   return () => {
  4.     // componentWillUnmount 的逻辑
  5.   };
  6. }, [dependencies]);
复制代码
2. 副作用管理

处置惩罚副作用:useEffect 在组件渲染后实行,用于处置惩罚须要在渲染后发生的副作用,比方更新 DOM、设置订阅、发送网络哀求等。
清算副作用:
a. 组件卸载时(Unmount):当组件从界面上被移除时,React 会调用 useEffect 返回的扫除函数。这确保了任何与该组件相干的订阅、计时器或其他副作用在组件不再存在时被精确清算。
b. 在重新实行 effect 之前:假如 useEffect 的依赖项数组中的某个值发生了厘革,React 会在重新实行 effect 之前调用上一次 effect 的扫除函数。这克制了副作用的累积,并确保每次 effect 实行前的环境是干净的。
  1. useEffect(() => {
  2.   const subscription = someService.subscribe();
  3.   return () => {
  4.     subscription.unsubscribe();
  5.   };
  6. }, []);
复制代码
3. 依赖项数组

正确控制 effect 实行时机:依赖项数组 [dependencies] 答应你指定 effect 何时重新实行。只有当数组中的依赖项发生厘革时,effect 才会被触发。空数组的话只实行一次,相称于componentDidMount
克制不须要的更新:通过精确设置依赖项数组,可以克制不须要的 effect 实行,进步组件性能。
  1. useEffect(() => {
  2.   // 仅当 count 变化时执行
  3. }, [count]);
复制代码
4. 多次使用

拆分逻辑:可以在同一个组件中多次使用 useEffect,每个 effect 钩子可以处置惩罚差异的副作用逻辑,保持代码清晰。
  1. useEffect(() => {
  2.   // 处理订阅逻辑
  3. }, []);
  4. useEffect(() => {
  5.   // 处理数据获取逻辑
  6. }, [dataId]);
复制代码
5. 与闭包共同

访问最新的 state 和 props:useEffect 内部的函数会捕获到当前渲染周期的 state 和 props,确保副作用操纵基于最新的数据。
6. 支持异步操纵

处置惩罚异步任务:useEffect 可以轻松处置惩罚异步操纵,如数据获取和定时器。
  1. useEffect(() => {
  2.   async function fetchData() {
  3.     const result = await axios.get('/api/data');
  4.     setData(result.data);
  5.   }
  6.   fetchData();
  7. }, []);
复制代码
7. 镌汰样板代码

简化代码结构:相比于类组件的生命周期方法,useEffect 在函数组件中使用更加简便,镌汰了样板代码,使代码更易读。
优点总结
简便性:使函数组件可以大概方便地管理副作用,镌汰了对类组件的依赖。
可读性:通过拆分差异的 useEffect,逻辑更清晰,代码更易于维护。
性能优化:通过依赖项数组,克制了不须要的副作用实行,进步了应用性能。
同等性:提供了同一的方式来处置惩罚组件的副作用,镌汰了认知负担。
留意事项


  • 精确使用依赖项数组:确保在依赖项数组中包罗全部在 effect 中使用的外部变量,防止由于闭包导致的状态差异等标题。
  • 克制无穷循环:假如不慎遗漏依赖项,大概依赖项数组厘革过于频仍,大概导致 effect 无穷实行,造成性能标题。
  • 清算函数的告急性:对于订阅、计时器等副作用,肯定要在清算函数中举行清算,防止内存走漏。
示例代码
  1. import React, { useState, useEffect } from 'react';
  2. function ChatRoom({ roomId }) {
  3.   const [messages, setMessages] = useState([]);
  4.   useEffect(() => {
  5.     // 订阅聊天信息
  6.     const subscription = ChatAPI.subscribeToRoom(roomId, (newMessage) => {
  7.       setMessages((prevMessages) => [...prevMessages, newMessage]);
  8.     });
  9.     // 清理函数,取消订阅
  10.     return () => {
  11.       ChatAPI.unsubscribeFromRoom(roomId, subscription);
  12.     };
  13.   }, [roomId]); // 当 roomId 变化时,重新订阅
  14.   return (
  15.     <div>
  16.       {messages.map((message) => (
  17.         <p key={message.id}>{message.content}</p>
  18.       ))}
  19.     </div>
  20.   );
  21. }
复制代码
在上述示例中:
使用了 useEffect 来订阅和取消订阅谈天信息。
依赖项数组 [roomId] 确保当房间 ID 厘革时,重新实行 effect。
返回的清算函数确保在组件卸载或 roomId 厘革时,取消之前的订阅。
useEffetct是怎样拿到变量count最新的值?

示例:
  1. function Counter() {  
  2.   const [count, setCount] = useState(0);   
  3.   useEffect(() => {   
  4.     document.title = `You clicked ${count} times`;  
  5.   });  
  6.   return (   
  7.     <div>      
  8.       <p>You clicked {count} times</p>      
  9.       <button onClick={() => setCount(count + 1)}>        
  10.         Click me      
  11.       </button>   
  12.     </div>  
  13.   );
  14. }
复制代码
useEffect 中的函数可以大概读取到最新的 count 状态值,告急是由于 JavaScript 中的闭包机制和 React 函数组件的渲染逻辑。
1. 每次渲染都会创建新的函数作用域

新的渲染上下文:在 React 中,每当组件的状态或属性发生厘革时,组件都会重新渲染。对于函数组件来说,这意味着组件函数会被重新实行,天生新的渲染结果。
新的变量和函数:每次渲染都会创建新的作用域,此中的变量(如 count)和函数(如通报给 useEffect 的函数)都是新的。
2. 闭包捕获最新的状态值

闭包机制:JavaScript 中,函数会捕获其外部作用域中使用的变量。这意味着在每次渲染时,useEffect 中的函数都会捕获到当次渲染时的 count 值。
最新的 count 值:由于 count 是在组件函数实行时界说的,每次渲染都会得到最新的状态值。useEffect 中的函数在被调用时,使用的就是这个最新的 count 值。
3. useEffect 的实行时机

在渲染后实行:useEffect 中的函数会在组件渲染到屏幕后实行。纵然它在渲染期间界说,但实行是在 DOM 更新之后。
每次渲染后实行:在您的示例中,由于没有指定依赖项数组,useEffect 会在每次渲染后实行,因此每次都会使用最新的 count 值。
综合表明

  • 函数组件的特性:函数组件在每次渲染时都会重新实行函数体,天生新的 count、setCount,以及新的 useEffect 中的函数。
  • 闭包捕获:useEffect 中的函数在界说时,捕获了当次渲染的 count 值。当 effect 被实行时,它使用的就是这个捕获的值。
  • 最新的状态值:由于每次渲染都会天生新的 count,useEffect 中的函数总是可以大概获取到最新的 count 值。
useLayoutEffect 与 useEffect

1. useLayoutEffect:

在欣赏器完成结构和绘制之前同步实行。
实用于须要读取结构信息并同步修改 DOM 的场景。
会壅闭欣赏器绘制,影响性能,审慎使用。
2. useEffect:

在欣赏器绘制之后异步实行。
不会壅闭渲染,更常用。
示例场景:
使用 useLayoutEffect:丈量 DOM 元素的尺寸或位置,然后立刻修改结构。
createRef和useRef

1. createRef

创建方式:React.createRef()。
实用于:告急在 类组件(Class Components) 中使用。
示例:
  1. import React from 'react';
  2. class MyComponent extends React.Component {
  3.   constructor(props) {
  4.     super(props);
  5.     this.myRef = React.createRef();
  6.   }
  7.   componentDidMount() {
  8.     // 通过 this.myRef.current 访问 DOM 元素或子组件实例
  9.     console.log(this.myRef.current);
  10.   }
  11.   render() {
  12.     return <div ref={this.myRef}>Hello World</div>;
  13.   }
  14. }
复制代码
每次调用 createRef() 都会返回一个新的 Ref 对象。这意味着假如在函数组件中使用 createRef,每次渲染都会创建一个新的 Ref,而不是恒久化的。
实用于类组件:在类组件的构造函数中创建一次 Ref,并在整个组件生命周期中保持同等。
2. useRef

创建方式:const refContainer = useRef(initialValue)。
实用于:函数组件(Function Components),由于它是一个 Hook。
示例:
  1. import React, { useRef, useEffect } from 'react';
  2. function MyComponent() {
  3.   const myRef = useRef(null);
  4.   useEffect(() => {
  5.     // 通过 myRef.current 访问 DOM 元素或保存任何可变值
  6.     console.log(myRef.current);
  7.   }, []);
  8.   return <div ref={myRef}>Hello World</div>;
  9. }
复制代码
useRef 返回的 Ref 对象在整个组件生命周期中是恒久的。无论组件怎样重新渲染,useRef 返回的对象始终指向同一个引用。
不但可以用于获取 DOM 元素,还可以用于生存恣意可变值,雷同于在类组件中使用实例属性。
不会在组件重新渲染时重新初始化。
特性对比

特性createRefuseRef实用组件范例类组件(Class Components)函数组件(Function Components)调用时机通常在构造函数中调用一次在函数组件内的恣意位置(依照 Hook 规则)每次渲染是否创建新 Ref是,每次调用都会创建新的 Ref 对象否,useRef 返回的对象在整个生命周期中保持稳定用途获取 DOM 元素或子组件实例获取 DOM 元素、生存可变值、存储任何可变数据可恒久化的可变值否,告急用于引用 DOM 或组件实例是,可用于存储恣意可变值,不会触发重新渲染
回复

使用道具 举报

登录后关闭弹窗

登录参与点评抽奖  加入IT实名职场社区
去登录
快速回复 返回顶部 返回列表