React纯UI CRUD组件:主联系人置顶及sortBy排序失效问题排查
I've looked into your issue, and the root cause is actually related to how you're updating your React state, not the sortBy logic itself. Let me break this down for you:
The Problem: Mutable State Updates
In your broken implementation, you're directly modifying the original contacts array/objects and then passing the same reference back to setContacts. React relies on reference changes to detect state updates and trigger re-renders. When you mutate the original array (like using push, splice, or directly editing object properties), the array reference stays the same, so React doesn't re-run the render cycle—meaning your sortBy logic never gets executed after those updates.
The Fix: Immutable State Updates
You need to update your state in an immutable way, creating new arrays/objects instead of modifying the existing ones. Here's how to fix each of your handler functions:
Setting Primary Contact
Replace your current mutable update with a new array created viamap:const handleSetPrimary = (id) => { setContacts(contacts.map(contact => ({ ...contact, primary: contact.id === id }))); };Adding a New Contact
Instead of pushing to the original array, spread the existing contacts into a new array and add the new contact:const handleAdd = () => { const newContact = { id: Date.now(), name: 'New Contact', primary: false }; setContacts([...contacts, newContact]); };Deleting a Contact
Usefilterto return a new array excluding the deleted contact:const handleDelete = (id) => { setContacts(contacts.filter(contact => contact.id !== id)); };Updating Contact Name
Usemapto create a new object for the updated contact:const handleUpdateName = (id, newName) => { setContacts(contacts.map(contact => contact.id === id ? { ...contact, name: newName } : contact )); };
Why Your sortBy Logic Works Once Fixed
Your existing sorting logic sortBy(contacts, o => !o.primary) is correct:
!o.primaryreturnsfalsefor primary contacts (sinceo.primaryistrue), andtruefor non-primary ones.sortBysorts values in ascending order, sofalse(primary) comes beforetrue(non-primary), putting your primary contact at the top.
Once you fix the state updates to be immutable, React will detect the new array reference, re-run the render cycle, and apply the sorting correctly every time the state changes.
内容的提问来源于stack exchange,提问作者Sharon Chai

