简体   繁体   English

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

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

In my JSX, I'm, mapping through an array of objects (imported from a local JS file) to display a set of icons with a key, id and alt tag.在我的 JSX 中,我通过一组对象(从本地 JS 文件导入)进行映射,以显示一组带有键、id 和 alt 标记的图标。

I use hooks to set a state to an empty string.我使用钩子将状态设置为空字符串。 I want to use an onClick event (passed to the HeroIcons component) to replace this state with the id of the clicked icon (that id is a string).我想使用 onClick 事件(传递给HeroIcons组件)将此状态替换为单击图标的 ID(该 ID 是一个字符串)。 Here's the code:这是代码:

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;

Inside the heroIcons component:在 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;

When clicking on an icon (created by the map function), the id isn't logged to the console.单击图标(由 map 函数创建)时,id 不会记录到控制台。 However, when I furiously click it many times, sometimes an id DOES get logged.但是,当我疯狂地多次单击它时,有时会记录一个 id。 This gives me a hint that this click event could be causing the map function to re-run and prevent the normal console log这给了我一个提示,这个点击事件可能导致地图功能重新运行并阻止正常的控制台日志在此处输入图像描述

How could I fix this this issue?我该如何解决这个问题?

First you have to use e.currentTarget.id instead of e.target.id so you get the id of current image.首先,您必须使用e.currentTarget.id而不是e.target.id ,这样您才能获得当前图像的id

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

Second useState Hook needs you to handle the callback to use log the value of the current state, while it doesn't accept the callback like setState .第二个useState Hook 需要你处理回调以使用log当前状态的值,但它不接受像setState这样的callback You can use useEffect but It would better if you use the value of e.currentTarget.id ;您可以使用useEffect但最好使用e.currentTarget.id的值;

This is because you hero is not updated at the time of console so you need to use useEffect hook when that value is updated这是因为您的hero在控制台时未更新,因此您需要在更新该值时使用useEffect挂钩

 const setCurrentHero = e => { currentHero(e.target.id); console.log(hero); }; useEffect(() => { console.log('Hero', hero); }, [hero]);

why not just set the value in the render:为什么不直接在渲染中设置值:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM