Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

153
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar

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 Denunciar

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda