MST

星途 面试题库

面试题:React Hooks 中 useState 的使用细节

请阐述在 React 函数组件中使用 useState 钩子的基本语法,并说明当多个状态需要更新时,应如何正确使用 useState 避免常见的问题,例如状态更新的合并以及闭包陷阱。
26.7万 热度难度
前端开发React

知识考点

AI 面试

面试题答案

一键面试

useState 基本语法

在 React 函数组件中,useState 用于在函数组件中添加状态。其基本语法如下:

import React, { useState } from'react';

function MyComponent() {
  // 声明一个状态变量和更新该状态变量的函数
  const [stateVariable, setStateFunction] = useState(initialValue); 

  return (
    <div>
      <p>{stateVariable}</p>
      <button onClick={() => setStateFunction(newValue)}>更新状态</button>
    </div>
  );
}

其中,useState 接收一个初始值作为参数,并返回一个数组。数组的第一个元素是当前状态值,第二个元素是用于更新该状态的函数。

多个状态更新

  1. 状态更新合并
    • React 不会自动合并多个 useState 的更新。例如,如果有两个状态 countname
    import React, { useState } from'react';
    
    function MultipleStateComponent() {
      const [count, setCount] = useState(0);
      const [name, setName] = useState('');
    
      const handleClick = () => {
        setCount(count + 1);
        setName('new name');
      };
    
      return (
        <div>
          <p>Count: {count}</p>
          <p>Name: {name}</p>
          <button onClick={handleClick}>更新状态</button>
        </div>
      );
    }
    
    • 这里的两个 setState 操作是独立的,不会互相影响。如果想要合并状态更新,可以将多个状态放在一个对象中,使用一个 useState 来管理:
    import React, { useState } from'react';
    
    function MultipleStateComponent() {
      const [state, setState] = useState({
        count: 0,
        name: ''
      });
    
      const handleClick = () => {
        setState(prevState => ({
         ...prevState,
          count: prevState.count + 1,
          name: 'new name'
        }));
      };
    
      return (
        <div>
          <p>Count: {state.count}</p>
          <p>Name: {state.name}</p>
          <button onClick={handleClick}>更新状态</button>
        </div>
      );
    }
    
  2. 闭包陷阱
    • 闭包陷阱通常发生在事件处理函数或异步操作中。例如:
    import React, { useState } from'react';
    
    function ClosureTrapComponent() {
      const [count, setCount] = useState(0);
    
      const handleClick = () => {
        setTimeout(() => {
          setCount(count + 1);
        }, 1000);
      };
    
      return (
        <div>
          <p>Count: {count}</p>
          <button onClick={handleClick}>延迟更新</button>
        </div>
      );
    }
    
    • 在这个例子中,setTimeout 中的 count 捕获的是 handleClick 函数定义时的 count 值,而不是最新的 count 值。为了避免这种情况,可以使用 prevState
    import React, { useState } from'react';
    
    function ClosureTrapComponent() {
      const [count, setCount] = useState(0);
    
      const handleClick = () => {
        setTimeout(() => {
          setCount(prevCount => prevCount + 1);
        }, 1000);
      };
    
      return (
        <div>
          <p>Count: {count}</p>
          <button onClick={handleClick}>延迟更新</button>
        </div>
      );
    }
    
    • 使用 prevState 可以确保我们基于最新的状态值进行更新,而不是捕获的旧值。