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

163
Views
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 answers
Answer question

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 Report

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 Report

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 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!