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.
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). 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:
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. However, when I furiously click it many times, sometimes an id DOES get logged. 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.
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
. You can use useEffect
but It would better if you use the value of 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
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)}
/>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.