useState、useEffect基础用法
React 提供了许多强大的 Hooks,其中 useState 和 useEffect 是最常用的两个。它们分别用于管理组件的状态和执行副作用(side effects)。本章将详细介绍这两个 Hook 的基础用法。
1. useState
useState 是一个用于在函数组件中声明状态的 Hook。它返回一个数组,其中包含当前状态的值和一个更新状态的函数。
1.1 基本语法
const [state, setState] = useState(initialState);
- state:当前状态的值。
- setState:用于更新状态的函数。
- initialState:状态的初始值,useState 接受一个初始值作为参数,该初始值可以是任何类型的数据(数字、字符串、数组、对象等)。
1.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>
);
}
export default Counter;
说明:
- useState(0) 初始化状态为 0,并且通过 setCount 更新状态。
- 每次点击按钮时,increment 函数会调用 setCount 来更新 count 状态。
1.3 使用对象或数组作为状态
import React, { useState } from 'react';
function UserProfile() {
const [user, setUser] = useState({ name: 'John', age: 30 });
const updateName = () => {
setUser({ ...user, name: 'Alice' });
};
return (
<div>
<p>Name: {user.name}</p>
<p>Age: {user.age}</p>
<button onClick={updateName}>Change Name</button>
</div>
);
}
export default UserProfile;
说明:
使用对象或数组作为状态时,更新状态需要确保保持对象的不可变性(例如使用扩展运算符 ...)。
2. useEffect
useEffect 是一个用于执行副作用操作的 Hook。副作用指的是组件渲染后需要执行的操作,比如数据获取、订阅、手动操作 DOM 等。
2.1 基本语法
useEffect(() => {
// 副作用代码
}, [dependencies]);
- 第一个参数是一个函数,包含副作用代码。
- 第二个参数是一个依赖数组,当数组中的变量发生变化时,副作用函数会被重新执行。如果省略第二个参数,副作用会在每次渲染后执行。
2.2 示例:使用 useEffect 请求数据
import React, { useState, useEffect } from 'react';
function DataFetcher() {
const [data, setData] = useState(null);
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/posts')
.then((response) => response.json())
.then((data) => setData(data));
}, []); // 空数组表示副作用只会在组件挂载时执行一次
return (
<div>
<h1>Fetched Data</h1>
{data ? (
<ul>
{data.map((item) => (
<li key={item.id}>{item.title}</li>
))}
</ul>
) : (
<p>Loading...</p>
)}
</div>
);
}
export default DataFetcher;
说明:
useEffect 用于在组件挂载时请求数据。 依赖数组 [] 表示副作用只会在组件首次渲染时执行一次。
2.3 示例:根据 props 更新副作用
import React, { useState, useEffect } from 'react';
function Timer({ start }) {
const [count, setCount] = useState(start);
useEffect(() => {
const interval = setInterval(() => {
setCount((prevCount) => prevCount + 1);
}, 1000);
return () => clearInterval(interval); // 清理副作用
}, [start]); // 当 `start` 改变时重新执行副作用
return <p>Timer: {count}</p>;
}
export default Timer;
说明: useEffect 中的副作用函数会根据 start 属性的变化重新执行。clearInterval 用于清理副作用,避免内存泄漏。
3. useState 与 useEffect 的配合使用
useState 和 useEffect 经常一起使用,尤其是在处理异步操作时。常见的场景是使用 useEffect 进行数据获取,并通过 useState 更新数据状态。
示例:获取数据并更新状态
import React, { useState, useEffect } from 'react';
function PostList() {
const [posts, setPosts] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch('https://jsonplaceholder.typicode.com/posts')
.then((response) => response.json())
.then((data) => {
setPosts(data);
setLoading(false);
});
}, []); // 只在首次渲染时执行
return (
<div>
{loading ? <p>Loading...</p> : <ul>{posts.map((post) => <li key={post.id}>{post.title}</li>)}</ul>}
</div>
);
}
export default PostList;
说明:
- useState 用于存储获取到的 posts 数据和 loading 状态。
- useEffect 处理数据获取,并在数据加载完成后更新状态。
4. 小结
- useState 用于声明组件的状态,并提供一个更新状态的函数。可以用于管理任何类型的数据。
- useEffect 用于处理副作用,常用于数据获取、订阅和手动操作 DOM。通过依赖数组控制副作用的执行时机。
- useState 和 useEffect 经常一起使用,特别是在处理异步操作和更新状态时。
掌握 useState 和 useEffect 是 React 开发的基础,它们帮助你实现动态和响应式的用户界面。
