当前位置: 首页 > news >正文

灰色项目网站代做分销系统小程序开发

灰色项目网站代做,分销系统小程序开发,做网站的zk啥,北京最新消息发布文章目录 React 的 useEffect一、什么是副作用(Side Effects)?二、useEffect 的基本用法三、依赖数组的三种情况1. 无依赖数组(每次渲染后都执行, 不推荐)2. 空依赖数组(仅在挂载时执行一次)3. …

文章目录

  • React 的 useEffect
    • 一、什么是副作用(Side Effects)?
    • 二、useEffect 的基本用法
    • 三、依赖数组的三种情况
      • 1. 无依赖数组(每次渲染后都执行, 不推荐)
      • 2. 空依赖数组(仅在挂载时执行一次)
      • 3. 有依赖项(依赖变化时执行)
    • 四、常见应用场景
      • 1. 数据请求:根据参数动态加载数据 ​
      • 2. 事件监听:窗口大小变化时更新状态 ​
      • 3. 定时器:倒计时功能 ​
      • 4. 动画帧(requestAnimationFrame)
      • 5. 本地存储同步
    • 五、清理函数(Cleanup Function)
    • 六、性能优化与注意事项
      • 1. 避免无限循环
      • 2. 依赖项是对象或数组时
      • 3. 按职责拆分副作用
    • 七、常见问题与解决方案
      • 1. 如何在 useEffect 中使用异步函数?
      • 2. 依赖项缺失导致逻辑错误
    • 八、总结与最佳实践

React 的 useEffect

useEffect 是 React Hooks 中最重要的 API 之一,用于处理组件中的副作用(Side Effects),例如数据请求、DOM 操作、订阅事件等。本文将从基础用法、核心原理、常见问题到最佳实践,全面解析 useEffect 的使用技巧。

一、什么是副作用(Side Effects)?

在 React 中,副作用是指那些与组件渲染结果无直接关系,但可能影响其他组件或外部系统的操作。例如:

  • 数据请求(API 调用)
  • 手动修改 DOM
  • 订阅事件(如 WebSocket、键盘事件)
  • 设置定时器

类组件中,副作用通常写在生命周期方法(如 componentDidMount、componentDidUpdate)中。而函数组件通过 useEffect 统一管理副作用。

二、useEffect 的基本用法

useEffect(() => {// 副作用逻辑return () => {/* 清理函数(可选) */}
}, [dependencies])
  • 第一个参数:一个包含副作用逻辑的函数(必填)
  • 第二个参数:依赖数组(可选),用于控制副作用的执行时机。
  • 返回值:清理函数(可选),用于在组件卸载或下次副作用执行前释放资源。

三、依赖数组的三种情况

1. 无依赖数组(每次渲染后都执行, 不推荐)

useEffect(() => {console.log('每次组件更新后执行')
})

​- ​ 行为 ​​:组件每次渲染(包括首次渲染和更新)后都会执行。
​- ​ 风险 ​​:可能导致性能问题或无限循环(如在副作用中修改状态)。

2. 空依赖数组(仅在挂载时执行一次)

useEffect(() => {console.log('仅在挂载时执行一次')
})
  • 行为 ​​:仅在组件首次渲染后执行一次,类似类组件的 componentDidMount。
    ​- ​ 用途 ​​:初始化操作(如请求初始数据、订阅事件)。

3. 有依赖项(依赖变化时执行)

useEffect(() => {console.log('当 count 变化时执行')
}, [count])

​​ - 行为 ​​:首次渲染后执行,后续仅在依赖项 count 变化时执行。
​​ - 关键点 ​​:依赖项必须是基本类型(如数字、字符串)或稳定引用(通过 useMemo/useCallback 包裹的复杂类型)。

四、常见应用场景

1. 数据请求:根据参数动态加载数据 ​

import { useState, useEffect } from 'react'
import axios from 'axios'function UserProfile({ userId }) {const [userData, setUserData] = useState(null)const [loading, setLoading] = useState(false)useEffect(() => {// 定义取消请求的标记let isCancelled = falseconst fetchUserData = async () => {try {setLoading(true)const response = await axios.get(`/api/users/${userId}`)// 仅在组件未卸载时更新状态if (!isCancelled) {setUserData(response.data)setLoading(false)}} catch (error) {if (!isCancelled) {setLoading(false)console.error('Fetch error:', error)}}}fetchUserData()// 清理函数:取消未完成的请求return () => {isCancelled = true}}, [userId]) // 当 userId 变化时重新加载数据return (<div>{loading ? 'Loading...' : userData && <div>{userData.name}</div>}</div>)
}

2. 事件监听:窗口大小变化时更新状态 ​

import { useState, useEffect } from 'react'function WindowSizeTracker() {const [windowSize, setWindowSize] = useState({width: window.innerWidth,height: window.innerHeight})useEffect(() => {// 定义事件处理函数const handleResize = () => {setWindowSize({width: window.innerWidth,height: window.innerHeight})}// 添加监听window.addEventListener('resize', handleResize)// 清理函数:移除监听return () => {window.removeEventListener('resize', handleResize)}}, []) // 空依赖数组:仅挂载时添加一次监听return (<div>Window Size: {windowSize.width}px x {windowSize.height}px</div>)
}

3. 定时器:倒计时功能 ​

import { useState, useEffect } from 'react'function CountdownTimer({ initialSeconds }) {const [seconds, setSeconds] = useState(initialSeconds)useEffect(() => {// 定义定时器const timer = setInterval(() => {setSeconds((prev) => {if (prev <= 1) {clearInterval(timer) // 倒计时结束清除定时器return 0}return prev - 1})}, 1000)// 清理函数:组件卸载时清除定时器return () => clearInterval(timer)}, []) // 空依赖数组:只在挂载时启动定时器return <div>Time Left: {seconds} seconds</div>
}

4. 动画帧(requestAnimationFrame)

import { useState, useEffect, useRef } from 'react'function AnimationBox() {const [position, setPosition] = useState(0)const requestRef = useRef() // 保存动画帧 IDconst animate = () => {setPosition((prev) => (prev >= 100 ? 0 : prev + 1))requestRef.current = requestAnimationFrame(animate) // 递归调用}useEffect(() => {requestRef.current = requestAnimationFrame(animate)// 清理函数:取消动画帧return () => cancelAnimationFrame(requestRef.current)}, []) // 空依赖数组:只在挂载时启动动画return (<div style={{ transform: `translateX(${position}px)` }}>Moving Box</div>)
}

5. 本地存储同步

import { useState, useEffect } from 'react'function ThemeSwitcher() {const [theme, setTheme] = useState(() => {// 从 localStorage 读取初始值const savedTheme = localStorage.getItem('theme')return savedTheme || 'light'})useEffect(() => {// 当 theme 变化时,同步到 localStoragelocalStorage.setItem('theme', theme)}, [theme]) // 依赖 theme,变化时触发return (<button onClick={() => setTheme(theme === 'light' ? 'dark' : 'light')}>Switch to {theme === 'light' ? 'Dark' : 'Light'} Theme</button>)
}

五、清理函数(Cleanup Function)

清理函数在以下时机执行:

  • 组件卸载时(类似 componentWillUnmount)。
  • 下次副作用执行前(依赖项变化时)。

示例:取消订阅

useEffect(() => {const subscription = eventEmitter.subscribe(() => {/* ... */})return () => subscription.unsubscribe()
}, [])

六、性能优化与注意事项

1. 避免无限循环

在副作用中直接修改依赖项会导致无限循环:

// ❌ 错误:每次更新后修改 count,触发重新渲染
useEffect(() => {setCount(count + 1)
}, [count])

2. 依赖项是对象或数组时

如果依赖项是对象或数组,即使内容相同,引用变化也会触发副作用:

// ❌ 可能意外触发
const config = { enabled: true };
useEffect(() => { ... }, [config]);// ✅ 用 useMemo 稳定引用
const config = useMemo(() => ({ enabled: true }), []);

3. 按职责拆分副作用

// 拆分数据请求和事件监听
useEffect(() => {/* 请求数据 */
}, [])
useEffect(() => {/* 监听事件 */
}, [])

七、常见问题与解决方案

1. 如何在 useEffect 中使用异步函数?

不能直接将 useEffect 的回调设为 async,但可以在内部定义异步函数:

useEffect(() => {const fetchData = async () => {const result = await axios.get(url)setData(result)}fetchData()
}, [url])

2. 依赖项缺失导致逻辑错误

启用 eslint-plugin-react-hooks 规则,确保依赖项完整。

八、总结与最佳实践

  1. 明确依赖项 ​​:始终填写依赖数组,避免遗漏。
  2. 拆分副作用 ​​:不同逻辑使用多个 useEffect。
  3. 及时清理资源 ​​:防止内存泄漏。
  4. 稳定引用 ​​:使用 useCallback 和 useMemo 处理复杂依赖。

通过合理使用 useEffect,可以写出更清晰、健壮的 React 组件。

http://www.dtcms.com/a/543620.html

相关文章:

  • 自己做网站帮公司出认证证书违法吗淄博周村专业网站建设公司
  • 北京网站建设案例百度一下生活更好
  • 电子商务运营网站wordpress多站点子域名
  • 网站建设不用虚拟主机ico交易网站怎么做
  • 专业公司网站开发服务阿里巴巴友情链接怎么设置
  • 网站开发的高级阶段包括vs2017网站开发时修改的页面未变化
  • 做热饮店网站凯里建设网站
  • 网站开发系统调研目的电力工程造价信息网
  • 关于网站建设的问卷调查网站开发外包合同范本
  • 有什么网站做可以国外的生意湖州网站建设哪家好
  • 广州网站制作公司多少钱网络设计专业可以学什么
  • 中石油第六建设公司网站中铁建设集团门户网登录失败
  • 山东信达建设有限公司网站vps网站管理器
  • 怎么做自己的网站推广离石做网站的公司
  • 做网站只开发手机端可不可以太原小程序开发定制
  • 北京网站开发网站开发公司wordpress md5工具
  • 专业做写生的网站花生壳如何做网站
  • 异构国际设计公司网站常州app制作
  • 勒索做钓鱼网站的人wordpress 前端模板
  • php网站开发练手项目凡科登录电脑版
  • 户外网站 整站下载网站开发怎么在页面上调用高德地图显示位置
  • 深州市住房保障和城乡建设局网站网站建设工作流程html
  • 广东网站建设咨询电话网站不显示内容
  • 自己做网站需要学什么东西wordpress怎么防站
  • 代客做网站祥云县住房和城乡建设局网站
  • 网站建设jiage网站开发php和ui
  • 网站建设后怎么赚钱小程序制作平台开发
  • .tv做网站怎么样定制网络机顶盒
  • 高端html5网站设计工作室织梦模板 dedecms5.7应用下载安装
  • 建设网站买了域名还要什么资料北京网站公司哪家好