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

166
Vistas
Adding loading state to map function causes items to display as loading

I have a map function displaying items:

 {data.map((item, index) => ())}

Within this function I would like to have an onClick that conditionally displays a loading state when loading is true.

const [loading, setLoading] = useState(false)

{data.map((item, index) => (
   <span
     onClick={() =>
     handleDelete()}>
  {loading ? (
    <LoadingSpinner />
       ) : (
    <TrashIcon />)} 
</span>
))}

When I do this it causes all items in the list to display the loading state, not just the item clicked on.

Is there a way I can achieve this using the index?

about 4 years ago · Juan Pablo Isaza
3 Respuestas
Responde la pregunta

0

All your map items are listening to a single boolean state value, instead, you can keep track of the index of the clicked item, or if you want to be able to click and show the loading state for multiple items you can use an array or Set.

Below is an approach using Set

const [loadingIndices, setLoadingIndices] = useState(new Set());
{data.map((item, index) => (
   <span
     onClick={() =>
     handleDelete(index)}>
  {loadingIndices.has(index) ? (
    <LoadingSpinner />
       ) : (
    <TrashIcon />)} 
</span>
))}

Now in your handleDelete function, you can add index of the clicked element to the set in state.

handleDelete = (selectedIndex) => {
  setLoadingIndices((prev) => new Set([...prev, selectedIndex]));
  // ...
  // ...
  // And to remove the element from loading state
  setLoadingIndices((prev) => {
    const updated = new Set(prev);
    updated.delete(selectedIndex);
    return updated;
  });
};
about 4 years ago · Juan Pablo Isaza Denunciar

0

You should move your state in to the items instead of the parent. Updating state inside the parent component will cause all children to re-render.

const childComponent = (props) => { // you can pass the main loading state as a starting point
const [loading,setLoading] = useState(props.loading) // initial loader state
if(loading) return <LoadingSpinner />
return (
   <button onClick={()=> setLoading(prev => !prev)} /> 
)}

you can then mutate this to display different elements using if statements like above.

about 4 years ago · Juan Pablo Isaza Denunciar

0

If you don't mind the re-render of children, You can use this index logic.

const [loading, setLoading] = useState(null);

const handleDelete = (index) => {
    setLoading(index);
}

{data.map((item, index) => (
   <span
     onClick={() =>
      handleDelete(index)}>
  {loading === index ? (
    <LoadingSpinner />
       ) : (
    <TrashIcon />)} 
</span>
))}
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