0

Currently I'm working on a react project, but I'm seeing some unexpected behavior when sorting an array of stateful child components.

If I have a parent component

export function Parent(){
  const [children, setChildren] = useState([
      {name:'Orange',value:2},
      {name:'Apple',value:1},
      {name:'Melon',value:3}
  ])
  var count = 0
  function handleSort() {
      var newChildren=[...children]
      newChildren.sort((a,b)=>{return a.value-b.value})
      setChildren(newChildren)
  }
  return (
      <div>
          <button onClick={handleSort}>Sort</button>
          {children.map((child) => {
            count++
            return(<ChildComp key={count} details={child}/>)
          })}
      </div>
  )
}

And a child component

function ChildComp(props){
  const[intCount,setIntCount] = useState(0)
  function handleCount(){
      setIntCount(intCount+1)
  }
  return (
      <div>
          <p>{props.details.name}</p>
          <button onClick={handleCount}>{intCount}</button>
      </div>
  )
}

When the page first renders everything looks great, three divs render with a button showing the number of times it was clicked and the prop name as it was declared in the array. I've noticed that when I sort, it sorts the props being passed to the child components which then rerender, but the intCount state of the child component stays tied to the original location and is not sorted. is there any way to keep the state coupled with the array element through the sort while still maintaining state data at the child level, or is the only way to accomplish this to raise the state up to the parent component and pass a callback or dispatch to the child to update it?

0

1 Answer 1

2

The count is not is not sorted. It just got updated when you sorted.

Keys help React identify which items have changed, are added, or are removed. Keys should be given to the elements inside the array to give the elements a stable identity

Every time you sort, key stay the same, as you use count.

Try using value as key

export function Parent(){
  // ....
  return (
      <div>
          <button onClick={handleSort}>Sort</button>
          {children.map(child => {
            return <ChildComp key={child.value} details={child}/> // key is important
          })}
      </div>
  )
}

More info: https://reactjs.org/docs/lists-and-keys.html#keys

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

1 Comment

Thank you, that fixed it, I didn't even consider the fact that I was recreating the keys each time it rendered.

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.