943 字
2 分钟
useState

useState
useState 是 React 中最基础的 Hook,它允许函数组件拥有自己的状态(state),是 React 官方提供的用于在函数组件中管理局部状态的核心 Hook。
在 React 16.8 引入 Hooks 之前,函数组件本身无法拥有状态,只能通过类组件的 this.state 和 this.setState 管理状态,useState 填补了这一空白。
核心作用
- 为函数组件添加局部状态:让无状态的函数组件可以维护自身的可变状态,状态会在组件重新渲染时被保留,且状态更新会触发组件重新渲染。
- 状态更新与触发重渲染:通过 useState 返回的更新函数修改状态,React 会根据新状态重新渲染组件,保证视图与状态同步。
- 独立的状态管理:每个 useState 调用管理一个独立的状态变量,支持在单个组件中多次调用,实现多状态维度的分离管理。
使用方法
1. 基本语法
import { useState } from 'react';
function Component() { // 声明状态变量,返回值是一个数组:[当前状态值, 更新状态的函数] const [state, setState] = useState(initialState);
// 组件逻辑与渲染 return <div>{state}</div>;}initialState:状态的初始值,可以是任意类型(数字、字符串、对象、数组等),仅在组件首次渲染时生效。state:当前的状态值,每次组件重渲染时会获取最新的状态。setState:更新状态的函数,调用后会修改state并触发组件重渲染。
2. 状态更新的两种方式
方式1:直接传入新值(适用于非依赖旧状态的场景)
const [count, setCount] = useState(0);// 直接设置新值setCount(1);方式2:传入更新函数(适用于依赖旧状态的场景)
const [count, setCount] = useState(0);// 基于旧状态计算新状态,确保拿到最新的旧值setCount(prevCount => prevCount + 1);3. 复杂类型状态(对象/数组)的更新
useState 不会自动合并对象/数组的状态,需要手动处理:
// 状态为对象const [user, setUser] = useState({ name: '张三', age: 20 });// 正确更新:合并旧对象属性 + 新属性setUser(prevUser => ({ ...prevUser, age: 21 }));
// 状态为数组const [list, setList] = useState([1, 2, 3]);// 正确更新:基于旧数组创建新数组setList(prevList => [...prevList, 4]);使用案例
案例1:基础计数器
实现点击按钮增加/减少数字的功能:
import { useState } from 'react';
function Counter() { // 声明计数状态,初始值为0 const [count, setCount] = useState(0);
return ( <div> <p>当前计数:{count}</p> {/* 直接传入新值 */} <button onClick={() => setCount(count - 1)}>减1</button> {/* 依赖旧状态,使用更新函数 */} <button onClick={() => setCount(prev => prev + 1)}>加1</button> </div> );}
export default Counter;案例2:表单输入绑定
管理输入框的状态,实现双向绑定效果:
import { useState } from 'react';
function InputForm() { // 声明输入框状态,初始值为空字符串 const [inputValue, setInputValue] = useState('');
// 处理输入变化 const handleChange = (e) => { setInputValue(e.target.value); };
return ( <div> <input type="text" value={inputValue} onChange={handleChange} placeholder="请输入内容" /> <p>你输入的内容:{inputValue}</p> </div> );}
export default InputForm;案例3:复杂状态(对象)管理
管理用户信息的多字段状态:
import { useState } from 'react';
function UserProfile() { // 初始状态为用户对象 const [user, setUser] = useState({ name: '李四', email: 'lisi@example.com', gender: 'male' });
// 更新姓名 const updateName = () => { setUser(prev => ({ ...prev, name: '李四更新' })); };
// 更新邮箱 const updateEmail = () => { setUser(prev => ({ ...prev, email: 'new-lisi@example.com' })); };
return ( <div> <h3>用户信息</h3> <p>姓名:{user.name}</p> <p>邮箱:{user.email}</p> <p>性别:{user.gender}</p> <button onClick={updateName}>修改姓名</button> <button onClick={updateEmail}>修改邮箱</button> </div> );}
export default UserProfile;使用注意事项
-
只能在函数组件/自定义Hook的顶层调用:
- 不能在循环、条件判断、嵌套函数中调用 useState,React 依赖 Hooks 的调用顺序来维护状态与 Hook 的关联,打乱顺序会导致状态错乱。 ❌ 错误示例:
function BadComponent() {if (true) {const [count, setCount] = useState(0); // 禁止!}return <div></div>;} -
初始值的执行时机:
initialState仅在组件首次渲染时生效,后续重渲染会忽略该值;如果初始值是通过复杂计算得到的(如大数组、复杂对象),建议传入函数避免重复计算:
// 推荐:初始值函数仅执行一次const [data, setData] = useState(() => {return heavyCalculation(); // 复杂计算逻辑}); -
状态更新的异步性:
- useState 的更新函数是异步的(批量更新),调用 setState 后不能立即获取最新的 state: ❌ 错误示例:
const [count, setCount] = useState(0);const handleClick = () => {setCount(count + 1);console.log(count); // 输出旧值,不是最新值};正确做法:依赖最新状态需用 useEffect 监听,或在更新函数中使用 prevState。
-
状态更新的不可变原则:
- React 状态是不可变的,不能直接修改 state(尤其是对象/数组),必须返回新的引用才能触发重渲染: ❌ 错误示例:
const [user, setUser] = useState({ name: '张三' });const updateUser = () => {user.name = '李四'; // 直接修改原对象,不会触发重渲染setUser(user);};正确示例:
const updateUser = () => {setUser(prev => ({ ...prev, name: '李四' })); // 返回新对象}; -
多次调用useState的独立性:
- 单个组件中多次调用 useState,每个状态相互独立,更新其中一个不会影响其他状态:
function MultiState() {const [count, setCount] = useState(0);const [text, setText] = useState('');// 更新count不会影响text,反之亦然return (<div><p>{count}</p><p>{text}</p></div>);} -
useState不支持自动合并对象:
- 与类组件的
this.setState不同,useState 更新对象时不会自动合并属性,必须手动使用扩展运算符(...)合并旧属性。
- 与类组件的
分享
如果这篇文章对你有帮助,欢迎分享给更多人!
部分信息可能已经过时
相关文章 智能推荐
.webp)
.webp)
.webp)
.webp)
.webp)
.webp)
.webp)
.webp)
.webp)
.webp)
.webp)
.webp)
