You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React按钮点击事件中console.log无法获取更新后状态的问题

问题原因

你遇到的是React的闭包陷阱:当点击add user创建user对象时,showName按钮的onClick回调会捕获当前作用域下的name值(此时是空字符串)。后续name更新触发组件重新渲染,但已经存入users数组的按钮仍绑定着旧闭包里的name,所以打印的始终是初始值。

解决方案

以下是两种可行的解决方式:

方案一:用useRef保存最新的name状态

useRef的.current属性会始终指向最新的值,不会被闭包固定:

export default function App() {
  const [users, setUsers] = React.useState([]);
  const [name, setName] = React.useState('');
  const nameRef = React.useRef(name);

  // 同步name状态到ref
  React.useEffect(() => {
    nameRef.current = name;
  }, [name]);

  const addUser = () => {
    const obj = {
      name: 'old user name',
      updateName: (
        <button onClick={() => setName('new user name')}>update name</button>
      ),
      showName: <button onClick={() => console.log(nameRef.current)}>show name</button>,
    };
    setUsers([obj, ...users]);
  };

  return (
    <div>
      <button onClick={addUser}> add user</button>
      {users &&
        users.map((user) => (
          <div key={user.name}>
            {user.name}
            {user.updateName}
            {user.showName}
          </div>
        ))}
    </div>
  );
}

方案二:不在users中存储JSX,只存数据,渲染时动态生成按钮

这种方式更符合React数据驱动视图的逻辑,每次组件渲染都会生成新的按钮,自然能拿到最新的name:

export default function App() {
  const [users, setUsers] = React.useState([]);
  const [name, setName] = React.useState('');

  const addUser = () => {
    // 仅存储数据,不存储JSX
    const obj = {
      id: Date.now(), // 添加唯一id作为列表key
      name: 'old user name',
    };
    setUsers([obj, ...users]);
  };

  return (
    <div>
      <button onClick={addUser}> add user</button>
      {users.map((user) => (
        <div key={user.id}>
          {user.name}
          <button onClick={() => setName('new user name')}>update name</button>
          <button onClick={() => console.log(name)}>show name</button>
        </div>
      ))}
    </div>
  );
}
补充说明

方案二更推荐,因为它遵循了React数据与视图分离的核心思想,代码更易维护,从根源上避免了闭包陷阱。如果业务需求必须在users中存储JSX,方案一的useRef方式可以有效解决闭包捕获旧值的问题。

内容的提问来源于stack exchange,提问作者rajasekhar gandavarapu

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 08:27:35