Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

152
Views
How to map components and ensure the component has the same attribute individually

Currently I have a map function that render a serial of image, and I realized that they share the same hover state, which means they will perform the same action when hovered. Is there are any standard practice to map duplicate components while assigning them unique/individual properies?

      {itemData.map((item) => (
        <ImageListItem key={item.img}>
          <img
            src={item.img}
            alt={item.title}
            loading="lazy"
            onMouseOver={() => {setHover(true)}}
            onMouseOut={() => {setHover(false)}}
            style={{ transform: hover ? 'scale(1.5, 1.5)' : null }}
          />
          <ImageListItemBar
            title={item.title}
            subtitle={item.author}
            actionIcon={
              <IconButton
                sx={{ color: 'rgba(255, 255, 255, 0.54)' }}
                aria-label={`info about ${item.title}`}
              >
                <InfoIcon />
              </IconButton>
            }
          />
about 4 years ago · Juan Pablo Isaza
3 answers
Answer question

0

To provide unique properties, you need to have something that uniquely identifies your image component and use it to manage your state. In your case, your state hover should be an array or an object, not a boolean. Since you are using item.img as a key, I assume it is unique and hence it can help in your state management like this:

const [hover, setHover] = useState({});
{itemData.map((item) => (
        <ImageListItem key={item.img}>
          <img
            src={item.img}
            alt={item.title}
            loading="lazy"
            onMouseOver={() => setHover({...hover, [item.img]: true})}
            onMouseOut={() => setHover({...hover, [item.img]: false})}
            style={{ transform: hover ? 'scale(1.5, 1.5)' : null }}
          />
          <ImageListItemBar
            title={item.title}
            subtitle={item.author}
            actionIcon={
              <IconButton
                sx={{ color: 'rgba(255, 255, 255, 0.54)' }}
                aria-label={`info about ${item.title}`}
              >
                <InfoIcon />
              </IconButton>
            }
          />
))
}
about 4 years ago · Juan Pablo Isaza Report

0

You should use a component, which create a unique state for each element, i wrote an easy to understand example.

import React, { useState } from "react"

const items = [
  {
    title: 'Card1',
    price: 100
  },
  {
    title: 'Card2',
    price: 50
  },
  {
    title: 'Card3',
    price: 200
  },
]

export default function App() {
  return (
    <>
      {
        items.map(element => {
          return(
            <Card {...element}/>
          )
        })
      }
    </>
  )
}

function Card({title, price, key}) {
  const [isHovered, setHover] = useState(false) 
  
  return (
    <>
    <div
    key={key}
    onMouseOver={() => {setHover(true)}}
    onMouseOut={() => {setHover(false)}}
    >
      <div>
        {title}
      </div>
      <h3>
        {
          isHovered && price
        }
      </h3>
    </div>
    </>
  );
}

I made the card price to show if hovered so you can see it works on each individual component.

Code sandbox if you want to check it out.

about 4 years ago · Juan Pablo Isaza Report

0

If you want the state to be in the parent without going all the way to an array or object, you can use a number instead. If only one item at a time is going to be active, you can just use the index of the active item as the state:

const { useState } = React;
const things = ["foo", "bar", "baz"];

function Component() {
  const [active, setActive] = useState(-1);
  const updateActivity = (index) => setActive(index === active ? -1 : index);
  return (
    <ul>
      {things.map((thing, index) => (
        <li>
          <button key={index} onClick={() => updateActivity(index)}>
            {index === active
              ? <strong>{thing}</strong>
              : thing}
          </button>
        </li>
      ))}
      <li>Value: {active}</li>
    </ul>
  );
}

ReactDOM.render(
  <Component />,
  document.getElementById("react")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.14.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.14.0/umd/react-dom.production.min.js"></script>
<div id="react"></div>

Alternatively, in cases where you want multiple items to be simultaneously active, you can use a "bit flag" approach where each bit of the value represents whether or not the corresponding index is active:

const { useState } = React;
const things = ["foo", "bar", "baz"];

function Component() {
  const [active, setActive] = useState(0);
  const updateActivity = (index) => setActive(active ^ Math.pow(2, index));
  return (
    <ul>
      {things.map((thing, index) => (
        <li>
          <button key={index} onClick={() => updateActivity(index)}>
            {active & Math.pow(2, index)
              ? <strong>{thing}</strong>
              : thing}
          </button>
        </li>
      ))}
      <li>Value: {active} ({active.toString(2).padStart(3, "0")})</li>
    </ul>
  );
}

ReactDOM.render(
  <Component />,
  document.getElementById("react2")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.14.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.14.0/umd/react-dom.production.min.js"></script>
<div id="react2"></div>

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!