To remove, replace, and reorder array items in React state, build a new array with filter, map, and slice. Each operation returns a fresh list instead of mutating the old one. React then sees a different array and updates the screen.
The same rule for every operation
All four operations share one rule: never mutate the array that is already in state. Start from the existing list and produce a new one with a non-mutating method.
Mutating methods change the old array in place, which hides the change from React. React compares arrays by reference, so the same array looks unchanged even after its contents move.
The basics of adding and transforming items live in updating arrays in state. This article focuses on the three operations that trip people up most: removing, replacing, and reordering. Each one below shows the smallest call that does the job.
Remove an item
To drop one item, keep every item except it. The filter callback returns true for items to keep and false for the one to remove.
setTodos(todos.filter((todo) => todo.id !== 1));The result contains every todo except the one with id 1. The original array is untouched, so React receives a different list and re-renders with the item gone.
Replace an item
To change one item, map over the list and return a new object only for the match. Every other item comes back as it was.
setTodos(
todos.map((todo) =>
todo.id === 1 ? { ...todo, done: true } : todo
)
);The matching item is replaced with a copy that flips done, while the rest keep their identity. Copying the object rather than mutating it keeps the previous state valid, which is the same rule from updating objects in state.
Transform every item
Sometimes every item needs the same change. map handles that too, returning a new array where each element is updated.
setTodos(
todos.map((todo) => ({ ...todo, priority: todo.priority + 1 }))
);Every todo comes back as a copy with its priority bumped. Because each object is replaced rather than mutated, the previous array stays valid for React's comparison.
Reorder with a copy
Sort and reverse mutate the array they are called on, so copy the list first. The copy can then be sorted or reversed freely.
const nextTodos = [...todos];
nextTodos.reverse();
setTodos(nextTodos);The copy holds the same items in a new array. Reversing it changes only the copy, so the order in state stays intact until you set the new list. To sort by a field, pass a comparator to sort, such as comparing titles alphabetically.
Insert at a position
Spread plus slice places an item at any index. The slice before the point comes first, then the new item, then the rest.
setTodos([
...todos.slice(0, 1),
{ id: 2, title: "New item", done: false },
...todos.slice(1),
]);This inserts the new item at index 1. The list keeps its order on both sides of the insertion point, and the new item lands exactly where you asked. Change the slice arguments to move the insertion point.
Common mistakes
- Calling splice, sort, or reverse on state directly mutates it and skips the render.
- Copying the array but mutating an object inside it still mutates shared data.
- Using the index as a key breaks when the list is reordered or filtered.
- Updating an item by index with direct assignment mutates the array.
Mutation is the root of most list bugs. If the screen does not update after an operation, the cause is usually a method that changed the old array in place. Reread the operation and look for a mutating call, which is the snapshot problem described in why state does not update immediately.
What to learn next
With these four operations, most lists are covered. Next, initialize that list lazily when building it is expensive, and move to a reducer when list changes grow complex enough to need one.
Rune AI
Key Insights
- Remove an item with filter.
- Replace an item with map.
- Reorder by copying the array, then sorting or reversing.
- Insert with spread plus slice.
- Never call splice, sort, or reverse on state directly.
Frequently Asked Questions
How do I remove one item from an array in state?
How do I reorder an array without mutating it?
Why does splice not update my list?
Conclusion
Remove items with filter, replace them with map, and reorder by copying the array first. Insert with spread plus slice, and never mutate the original list.
More in this topic
How to Build a Dropdown Menu in React
Build a React dropdown menu with the ARIA menu button pattern. Handle open and close, keyboard arrows, and clicks outside the menu.
How to Animate React Components with Motion
Animate React components with the Motion library. Set up motion, add enter, hover, and exit animations, and respect reduced motion.
Headless UI Components Explained: Logic Without Locked Styling
Understand headless UI components and how libraries like Radix give you unstyled, accessible behavior that you style yourself.