Home > Enterprise >  React not looping over array and rendering component correctly when array size is increased
React not looping over array and rendering component correctly when array size is increased

Time:08-10

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?

CodePudding user response:

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.

  • Related