React with Hooks:点击事件后如何正确更新状态?

React with Hooks: how to correctly update state after a click event?

在我的 JSX 中,我通过一组对象(从本地 JS 文件导入)进行映射,以显示一组带有键、id 和 alt 标记的图标。

我使用钩子将状态设置为空字符串。我想使用 onClick 事件(传递给 HeroIcons 组件)将此状态替换为单击图标的 ID(该 ID 是一个字符串)。这是代码:

import React, { useState } from "react";
import HeroImages from "../images/HeroImages";
import HeroIcons from "../components/HeroIcons";
import HeroShowcase from "../components/HeroShowcase";

const Heroes = () => {
  const [hero, currentHero] = useState("");

  const setCurrentHero = e => {
    currentHero(e.target.id);
    console.log(hero);
  };

  return (
    <div className="row">
      <div className="col-heroes">
        <ul className="hero-list">
          {/* map function below */}
          {HeroImages.map(({ id, src, altTag }) => (
            <HeroIcons
              key={id}
              id={id}
              src={src}
              altTag={altTag}
              setCurrentHero={setCurrentHero}
            />
          ))}
        </ul>
      </div>
      <div className="col-showcase">
        <HeroShowcase />
      </div>
    </div>
  );
};

export default Heroes;

heroIcons 组件内部:

import React from "react";

const HeroIcons = props => {
  return (
    <li key={props.id} id={props.id} onClick={props.setCurrentHero}>
      <img src={props.src} alt={props.altTag} />
    </li>
  );
};

export default HeroIcons;

单击图标(由地图功能创建)时,该 ID 不会记录到控制台。但是,当我疯狂地多次单击它时,有时会记录一个 id。这给了我一个提示,这个点击事件可能导致地图功能重新 运行 并阻止正常的控制台日志

我该如何解决这个问题?

首先 你必须使用 e.currentTarget.id 而不是 e.target.id 所以你得到当前图像的 id

  const setCurrentHero = e => {
    currentHero(e.currentTarget.id);
    console.log(hero);
  };

Second useState Hook 需要你处理回调以使用 log 当前状态的值,同时它不接受 callback 喜欢 setState。 您可以使用 useEffect 但最好使用 e.currentTarget.id;

的值

这是因为您 hero 在控制台时未更新,因此您需要在更新该值时使用 useEffect 挂钩

const setCurrentHero = e => {
  currentHero(e.target.id);
  console.log(hero);
};

useEffect(() => {
  console.log('Hero', hero);
}, [hero]);

为什么不直接在渲染中设置值:

<HeroIcons
          key={id}
          id={id}
          src={src}
          altTag={altTag}
          setCurrentHero={setCurrentHero(id)}
        />