You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从Mobx observable数组删除元素且不触发所有消费组件重渲染

问题原因

这不是Mobx配置错误,重渲染是两个写法问题共同导致的:

  1. 外层Todos组件是observer,订阅了todosStore.todos的变化,你无论用splice修改原数组还是filter替换数组,都会触发数组的变更通知,导致外层组件重渲染。
  2. 外层组件重渲染时,map循环内每次都会生成新的onDelete、onNameChange匿名函数,传递给Todo组件的props引用发生变化。observer组件默认会对props做浅比较,函数引用变化就会触发子组件重渲染,因此所有剩余Todo都会跟着重渲染。

解决方案

核心是让Todo组件的props保持稳定,最简单的改法是把回调逻辑移到Todo组件内部,不要通过父组件传递匿名回调:

1. 修改Todo组件

import { observer } from "mobx-react-lite";
import { combinedStores } from ".";

export default observer(({ todo }) => {
  const { todosStore } = combinedStores;

  const handleDelete = () => todosStore.removeTodo(todo.id);
  const handleNameChange = (e) => todosStore.editTodoName(todo.id, e.target.value);

  return (
    <div style={{padding:'10px',margin:'10px'}}>
      <p>ID: {todo.id}</p>
      <input onChange={handleNameChange} value={todo.name} />
      <p>Completed: {todo.completed ? 'true' : 'false'} 
        <button onClick={handleDelete} className="btn btn-danger">Delete</button>
      </p>            
    </div>
  )
})

2. 简化外层Todos组件

import { observer } from "mobx-react-lite";
import { combinedStores } from ".";
import Todo from "./Todo";

export default observer(() => {
  const { todosStore } = combinedStores;
  return (
    <div>
      {todosStore.todos.map(todo => (
        <Todo key={todo.id} todo={todo} />
      ))}
    </div>
  )
})

修改后Todo组件的props只有todo,只要todo对象本身没有被替换,引用就不会变,即使外层组件重渲染,子组件浅比较props不会触发重渲染,只有被删除的Todo会被移除,其余Todo都不会重复渲染。

额外优化(可选)

如果连外层组件的重渲染都想避免,可以用<Observer>组件单独包裹列表渲染部分,外层组件不需要加observer:

import { Observer } from "mobx-react-lite";
import { combinedStores } from ".";
import Todo from "./Todo";

export default () => {
  const { todosStore } = combinedStores;
  return (
    <div>
      <Observer>
        {() => todosStore.todos.map(todo => (
          <Todo key={todo.id} todo={todo} />
        ))}
      </Observer>
    </div>
  )
}

这种情况下只有<Observer>包裹的列表部分会在数组变化时重渲染,外层组件不会触发重渲染。

内容的提问来源于stack exchange,提问作者i.brod

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.05 22:09:02