React

observer与视图提取

mobx 类的响应式库,会使用 observer 修饰组件,让组件函数成为 observable 数据的 Reaction。
当前组件的 rerender 触发后,当前函数体,包括向内子组件的逻辑会被触发。
observable data 在使用时,会进行各种 get,set 验证,应尽量避开。
所以如果用 observable data 触发 rerender,需要尽量提出受影响部分的状态及视图,达到重执行的部分最小化(或重执行时,使用observable data的最小化):
且这些提取,应该越小越好。同时对 obserbable data 的修改,也是越小越好。

  1. // 只有 field.value 变化 rerender
  2. const Table = observer(() => {
  3. const arrayField = useField<ArrayFieldInstance>();
  4. const dataSource = Array.isArray(arrayField.value)
  5. ? arrayField.value.slice()
  6. : [];
  7. const formColumns = useTableFormColumns(testColumns, dataSource);
  8. return <List {...size} columns={formColumns} dataSource={dataSource} />;
  9. });
  10. // field.value 变化,不需要重执行,除 field 本身被修改,此函数体,永远不会 rerender
  11. const TableContainer = () => {
  12. const arrayField = useField<ArrayFieldInstance>();
  13. const getDefaultLineData = () =>
  14. testColumns.reduce((obj, column) => {
  15. obj[column.dataIndex] = getDefaultValue(column.valueType);
  16. return obj;
  17. }, {});
  18. return (
  19. <div>
  20. <div style={{ height: 200, width: 300 }}>
  21. <Table />
  22. </div>
  23. <Button onClick={() => arrayField.push(getDefaultLineData())}>Add</Button>
  24. </div>
  25. );
  26. };

因为 observable data 是 mutable 的,直接 .x = xxx 进行修改,修改及引用,始终维持最小范围。

observable 与 keep-alive

由于 observable data 的 mutable,且 observable data 变化后,使用的视图处会直接 forceUpdate,视图的更新是被动的,非受控的(开发者自己不会捣乱),所以如果一个使用了 observable data 的 vnode,可以安全地被缓存。