Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

162
Visualizações
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 Respostas
Responde à pergunta

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 Relatório

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 Relatório

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 Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda