React
observer与视图提取
mobx 类的响应式库,会使用 observer 修饰组件,让组件函数成为 observable 数据的 Reaction。
当前组件的 rerender 触发后,当前函数体,包括向内子组件的逻辑会被触发。
observable data 在使用时,会进行各种 get,set 验证,应尽量避开。
所以如果用 observable data 触发 rerender,需要尽量提出受影响部分的状态及视图,达到重执行的部分最小化(或重执行时,使用observable data的最小化):
且这些提取,应该越小越好。同时对 obserbable data 的修改,也是越小越好。
// 只有 field.value 变化 rerender
const Table = observer(() => {
const arrayField = useField<ArrayFieldInstance>();
const dataSource = Array.isArray(arrayField.value)
? arrayField.value.slice()
: [];
const formColumns = useTableFormColumns(testColumns, dataSource);
return <List {...size} columns={formColumns} dataSource={dataSource} />;
});
// field.value 变化,不需要重执行,除 field 本身被修改,此函数体,永远不会 rerender
const TableContainer = () => {
const arrayField = useField<ArrayFieldInstance>();
const getDefaultLineData = () =>
testColumns.reduce((obj, column) => {
obj[column.dataIndex] = getDefaultValue(column.valueType);
return obj;
}, {});
return (
<div>
<div style={{ height: 200, width: 300 }}>
<Table />
</div>
<Button onClick={() => arrayField.push(getDefaultLineData())}>Add</Button>
</div>
);
};
因为 observable data 是 mutable 的,直接 .x = xxx 进行修改,修改及引用,始终维持最小范围。
observable 与 keep-alive
由于 observable data 的 mutable,且 observable data 变化后,使用的视图处会直接 forceUpdate,视图的更新是被动的,非受控的(开发者自己不会捣乱),所以如果一个使用了 observable data 的 vnode,可以安全地被缓存。