怎么编写插件机制优化基于Antd Table封装表格的混乱代码

lxf2023-03-18 14:54:31

之后,在各个流程的相应位置,都通过 pluginContainer 执行相应的钩子函数即可:

export const TreeTable = React.forwardRef((props, ref) => {   // 省略上一部分代码……    // 这里拿到了 pluginContainer   const pluginContainer = usePluginContainer(     {       ...props,       plugins: [usePaginationPlugin, useLazyloadPlugin, useIndentLinePlugin],     },     pluginContext   );    // 递归遍历整个数据 调用钩子   const rewriteTree = ({     dataSource,     // 在动态追加子树节点的时候 需要手动传入 parent 引用     parentNode = null,   }) => {     pluginContainer.onRecord(parentNode);      traverseTree(dataSource, childrenColumnName, (node, parent, level) => {       // 这里执行插件的 onRecord 钩子       pluginContainer.onRecord(node, parent, level);     });   }    const rewrittenColumns = columns.map(rawColumn => {     //  这里把浅拷贝过后的 column 暴露出去     //  防止污染原始值     const column = Object.assign({}, rawColumn);     pluginContainer.onColumn(column);     return column;   });    const onExpand = async (expanded, record) => {     // 这里执行插件的 onExpand 钩子     pluginContainer.onExpand(expanded, record);   };    // 这里获取合并后的 components 传递给 Table   const components = pluginContainer.mergeComponents() });

之后,我们就可以把之前分页相关的逻辑直接抽象成 usePaginationPlugin:

export const usePaginationPlugin: TreeTablePlugin = (   props: ResolvedProps,   context: TreeTablePluginContext ) => {   const { forceUpdate, replaceChildList } = context;   const {     childrenPagination,     childrenColumnName,     rowKey,     indentLineDataIndex,   } = props;    const handlePagination = node => {     // 先加入渲染分页器占位节点   };    const rewritePaginationRender = column => {     // 改写 column 的 render     // 渲染分页器   };    return {     onRecord: handlePagination,     onColumn: rewritePaginationRender,   }; };

也许机智的你已经发现,这里的插件是以 use 开头的,这是自定义 hook的标志。

没错,它既是一个插件,同时也是一个 自定义 Hook。所以你可以使用 React Hook 的一切能力,同时也可以在插件中引入各种社区的第三方 Hook  来加强能力。

这是因为我们是在 usePluginContainer 中通过函数调用执行各个 usePlugin,完全符合 React Hook 的调用规则。

而懒加载节点相关的逻辑也可以抽象成 useLazyloadPlugin:

export const useLazyloadPlugin: TreeTablePlugin = (   props: ResolvedProps,   context: TreeTablePluginContext ) => {   const { childrenColumnName, rowKey, hasNexTKEy, onLoadMore } = props;   const { replaceChildList, expandedRowKeys, setExpandedRowKeys } = context;    // 处理懒加载占位节点逻辑   const handleNextLevelLoader = node => {};    const onExpand = async (expanded, record) => {     if (expanded && record[hasNextKey] && onLoadMore) {       // 处理懒加载逻辑     }   };    return {     onRecord: handleNextLevelLoader,     onExpand: onExpand,   }; };