0

I am storing an array in state and looping over it to display content on my website.

This is the function that I am calling to loop over the array stored in state:

  displayRefundSearchResults2 = () => {
    let refundSearchMatch = this.state.refundSearchMatch
    if(refundSearchMatch.length === 0){return}
    refundSearchMatch = refundSearchMatch.map(e => {e.userEvent = this.state.myEvent; return e})

    console.log('refundSearchMatch', refundSearchMatch.map(e => e._id), refundSearchMatch.map(e => e.checkedIn), '---------')

    return (<>{refundSearchMatch.map((ticket, index)=> {
      return( <div key={index}>
          <PurchasedTicket
            ticket = {JSON.parse(JSON.stringify(ticket))}
            requestFromOrganiser = {true}
            index={index}
          />
        </div>)}
        )}</>)
  }

and this is the child component's code:

const PurchasedTicket = (props) =>{


    return(
        <div className={'ticket-detail ticket-detail-price'}>
        <span>{'Ticket ID'}</span>
        <h2>{ticket._id}</h2>
        <span>{'Checked In'}</span>
        <h2>{String(ticket.checkedIn)}</h2>
        <span>{'--------'}</span>
    </div>
    )
}

export default withRouter(PurchasedTicket);

The data from the console.log matches perfectly with what shows up on screen at first:

refundSearchMatch (4) ['62e6ba84dd5e8206c7b6c969', '62e6ba84dd5e8206c7b6c96c', '62e6ba84dd5e8206c7b6c963', '62e6ba84dd5e8206c7b6c964'] (4) [false, false, false, false] ---------

web display before checking box

When I tick the checkbox I have coded so that an additional element is added to the array in state.

Now, the data from the console.log and the data on screen are different:

refundSearchMatch (5) ['62e6ba84dd5e8206c7b6c969', '62e6ba84dd5e8206c7b6c96c', '62e6ba84dd5e8206c7b6c965', '62e6ba84dd5e8206c7b6c963', '62e6ba84dd5e8206c7b6c964'] (5) [false, false, true, false, false] ---------

after clicking checkbox

React appears to be taking a short cut. It sees that there is an extra element in the array and it just displays the final element again. However, the new element was inserted into the middle of the array. This element is not displayed at all and the final element is duplicated instead.

How can I ensure react loops over the full contents of the array the second time?

3
  • This is why stable keys are so important. Please read through reactjs.org/docs/lists-and-keys.html. You'll need to use something besides the index so that React knows which elements are which. It's less of a React "shortcut" and more of a limitation (an understandable one) Commented Aug 10, 2022 at 14:13
  • Also I can't understand why JSON.parse(JSON.stringify(ticket)) would be necessary. It seems like a lot of work to get the same data you already had Commented Aug 10, 2022 at 14:19
  • Brilliant, thanks Brian. I used mongodb's unique id for the ticket as my key and now it is working as expected. If you would like to post your comment as the answer, I will accept it Commented Aug 10, 2022 at 14:25

1 Answer 1

1

The key required in a list of JSX elements is used for React to uniquely identify each component.

Think about it this way - React is given a list of 5 of component A, each with their own props. The next render, you want to remove one of those elements and add another one. React still sees 5 instances of component A; it has no good way of knowing that one should be removed and a new one should be added. So React just assumes they're all the same from before and only adjusts props for re-renders.

This causes issues like the one you are seeing. The fix is simple - provide React a better identifier for each component (like the ticket ID). This will help React understand when components should re-render vs when they should actually be removed or added.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.