用Hooks反应:单击事件后如何正确更新状态?

时间:2019-04-22 13:56:21

标签: javascript reactjs higher-order-functions rerender

在我的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。这给了我一个提示,即此click事件可能会导致map函数重新运行并阻止正常的控制台日志 enter image description here

如何解决此问题?

3 个答案:

答案 0 :(得分:0)

首先,您必须使用e.currentTarget.id而不是e.target.id,才能获得当前图像的id

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

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

答案 1 :(得分:0)

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

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

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

答案 2 :(得分:0)

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

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