在 React 中,useState 和 useEffect 是两个核心的 React Hook,用于处理组件的状态和副作用逻辑。以下是详细讲解:
1. useState:管理状态
useState 是一个 Hook,用于在函数组件中添加本地状态。
语法:
const [state, setState] = useState(initialState);
- 参数:
initialState:状态的初始值。
- 返回值:
state:当前状态的值。setState:更新状态的方法。
特点:
- 状态更新后,组件会重新渲染。
- 可以存储任意类型的值:字符串、数字、数组、对象等。
使用示例:
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0); // 初始化状态为 0
return (
<div>
<p>计数器值:{count}</p>
<button onClick={() => setCount(count + 1)}>增加</button>
<button onClick={() => setCount(count - 1)}>减少</button>
</div>
);
}
2. useEffect:处理副作用
useEffect 是一个 Hook,用于在函数组件中执行副作用逻辑。
副作用指的是任何在渲染过程中需要额外执行的逻辑,如:
- 数据获取(API 请求)。
- 订阅/取消订阅(如 WebSocket 或事件监听)。
- 手动操作 DOM。
语法:
useEffect(() => {
// 副作用逻辑
return () => {
// 清理逻辑(可选)
};
}, [dependencies]);
- 参数:
- 第一个参数是一个函数,用于定义副作用逻辑。
- 第二个参数是一个依赖数组,表示副作用的依赖项。
依赖数组的作用:
- 空数组
[]:只在组件挂载和卸载时执行一次。 - 不提供依赖数组:在每次渲染后都会执行。
- 特定依赖项:当依赖的变量发生变化时执行。
使用示例:
import React, { useState, useEffect } from 'react';
function Timer() {
const [count, setCount] = useState(0);
// 每秒增加一次计数
useEffect(() => {
const interval = setInterval(() => {
setCount((prevCount) => prevCount + 1);
}, 1000);
// 清理定时器
return () => clearInterval(interval);
}, []); // 空依赖数组,确保只在组件挂载时设置定时器
return <p>计时器:{count} 秒</p>;
}
useState 和 useEffect 的常见用法
1. 数据获取
import React, { useState, useEffect } from 'react';
function FetchData() {
const [data, setData] = useState(null);
useEffect(() => {
fetch('<https://api.example.com/data>')
.then((response) => response.json())
.then((data) => setData(data));
}, []); // 空依赖数组,确保只在组件挂载时执行一次
if (!data) {
return <p>加载中...</p>;
}
return <div>数据:{JSON.stringify(data)}</div>;
}
2. 事件监听
import React, { useState, useEffect } from 'react';
function WindowWidth() {
const [width, setWidth] = useState(window.innerWidth);
useEffect(() => {
const handleResize = () => setWidth(window.innerWidth);
window.addEventListener('resize', handleResize);
// 清理事件监听
return () => window.removeEventListener('resize', handleResize);
}, []); // 空依赖数组,确保只在挂载/卸载时设置和清理监听
return <p>窗口宽度:{width}</p>;
}
3. 动态依赖
import React, { useState, useEffect } from 'react';
function Counter() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log(`计数器更新:${count}`);
}, [count]); // 依赖 count,当 count 变化时执行
return (
<div>
<p>计数器:{count}</p>
<button onClick={() => setCount(count + 1)}>增加</button>
</div>
);
}
注意事项
-
状态更新是异步的:不要在状态更新后立即依赖其新值。
setCount(count + 1); // 异步,不能立即使用更新后的 count -
避免无限循环:在
useEffect中不要直接更新状态,否则会导致无限循环。useEffect(() => { setCount(count + 1); // 错误,会导致无限更新 }); -
清理副作用:对于订阅、定时器等需要在组件卸载时清理的副作用,要在
useEffect中返回清理函数。
通过灵活使用 useState 和 useEffect,可以轻松实现状态管理和副作用逻辑,充分发挥 React 的能力。
订阅 FreeMac
每周精选:Mac 高效技巧、免费替代付费软件、开发者工具推荐。用对你的 MacBook,省钱 + 提效。