mobx-react中如何让函数组件仅监听可观察数组内指定对象变化
Mobx实现表格单元格精准重渲染方案
核心Mobx概念
- Observable(可观察状态):通过
@observable标记Store中的data数组,使数组内每个元素的value成为响应式数据,状态变更时能被自动追踪。 - Observer(观察者组件):用
observer高阶组件包裹单元格函数组件,让组件仅在自身依赖的可观察值发生变更时触发重渲染。 - 精准依赖订阅:确保每个单元格组件只读取对应
rowIndex、colIndex的value,Mobx会自动锁定这个单一依赖,避免因其他单元格数据变化触发无意义的重渲染。
代码实现示例
1. Mobx Store定义
import { observable, action } from "mobx"; class TableStore { // 存储所有单元格数据,每个元素包含行列索引与对应值 @observable data: Array<{ rowIndex: number; colIndex: number; value: string }> = []; // 初始化5行10列的空数据 constructor() { for (let row = 0; row < 5; row++) { for (let col = 0; col < 10; col++) { this.data.push({ rowIndex: row, colIndex: col, value: "" }); } } } // 更新指定单元格的value @action updateCellValue(rowIndex: number, colIndex: number, newValue: string) { const targetCell = this.data.find(item => item.rowIndex === rowIndex && item.colIndex === colIndex); if (targetCell) { targetCell.value = newValue; } } } export const tableStore = new TableStore();
2. 单元格函数组件
import { observer } from "mobx-react-lite"; import { tableStore } from "./TableStore"; // 仅接收行列索引作为props const TableCell = observer(({ rowIndex, colIndex }: { rowIndex: number; colIndex: number }) => { // 仅读取当前单元格对应的value,Mobx会自动追踪这个依赖 const cellValue = tableStore.data.find(item => item.rowIndex === rowIndex && item.colIndex === colIndex)?.value || ""; return ( <input type="text" value={cellValue} onChange={(e) => tableStore.updateCellValue(rowIndex, colIndex, e.target.value)} /> ); }); export default TableCell;
3. 表格容器组件
import TableCell from "./TableCell"; const Table = () => { return ( <table> <tbody> {Array.from({ length: 5 }).map((_, rowIndex) => ( <tr key={rowIndex}> {Array.from({ length: 10 }).map((_, colIndex) => ( <td key={`${rowIndex}-${colIndex}`}> <TableCell rowIndex={rowIndex} colIndex={colIndex} /> </td> ))} </tr> ))} </tbody> </table> ); }; export default Table;
关键说明
- 每个
TableCell组件仅订阅自身对应的value,当其他单元格的value变更时,当前组件不会触发重渲染。 - 使用
mobx-react-lite的observer包裹函数组件,是函数组件中实现Mobx响应式的标准方式。 - Store中的
updateCellValue用@action修饰,确保状态变更在Mobx的事务中执行,避免不必要的中间状态触发重渲染。
内容的提问来源于stack exchange,提问作者HackHackHack
相关产品推荐
相关产品推荐

