@antv/s2-react
Version:
use S2 with react
149 lines • 7.21 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.useSpreadSheet = void 0;
const tslib_1 = require("tslib");
const s2_1 = require("@antv/s2");
const extends_1 = require("@antv/s2/extends");
const ahooks_1 = require("ahooks");
const lodash_1 = require("lodash");
const react_1 = tslib_1.__importDefault(require("react"));
const utils_1 = require("../utils");
const useEvents_1 = require("./useEvents");
const useLoading_1 = require("./useLoading");
const usePagination_1 = require("./usePagination");
const useResize_1 = require("./useResize");
function useSpreadSheet(props) {
const forceUpdate = (0, ahooks_1.useUpdate)();
const s2Ref = react_1.default.useRef(null);
const containerRef = react_1.default.useRef(null);
const wrapperRef = react_1.default.useRef(null);
const shouldInit = react_1.default.useRef(true);
const isDevMode = react_1.default.useMemo(() => {
try {
return process.env['NODE_ENV'] !== 'production';
}
catch (_a) {
return false;
}
}, []);
const { spreadsheet: customSpreadSheet, dataCfg, options, themeCfg, sheetType, onUpdate = lodash_1.identity, onUpdateAfterRender, onLoading, } = props;
/** 保存重渲 effect 的 deps */
const updatePrevDepsRef = react_1.default.useRef([dataCfg, options, themeCfg]);
const { loading, setLoading } = (0, useLoading_1.useLoading)(s2Ref.current, props.loading);
const pagination = (0, usePagination_1.usePagination)(s2Ref.current, props.options);
(0, useEvents_1.useEvents)(props, s2Ref.current);
const renderSpreadSheet = react_1.default.useCallback((container) => {
const s2Options = (0, utils_1.getSheetComponentOptions)(options);
if (customSpreadSheet) {
return customSpreadSheet(container, dataCfg, s2Options);
}
if (sheetType === 'table') {
return new s2_1.TableSheet(container, dataCfg, s2Options);
}
if (sheetType === 'pivotChart') {
return new extends_1.PivotChartSheet(container, dataCfg, s2Options);
}
return new s2_1.PivotSheet(container, dataCfg, s2Options);
}, [sheetType, options, dataCfg, customSpreadSheet]);
const buildSpreadSheet = react_1.default.useCallback(() => tslib_1.__awaiter(this, void 0, void 0, function* () {
var _a;
setLoading(true);
const s2 = renderSpreadSheet(containerRef.current);
s2.setThemeCfg(props.themeCfg);
yield s2.render();
setLoading(false);
s2Ref.current = s2;
/**
* 子 hooks 内使用了 s2Ref.current 作为 deps
* forceUpdate 一下保证子 hooks 能 rerender
*/
forceUpdate();
(_a = props.onMounted) === null || _a === void 0 ? void 0 : _a.call(props, s2Ref.current);
}), [props, renderSpreadSheet, setLoading, forceUpdate]);
// 适用于监听 loading 状态, 组件外部使用 <Spin /> 等场景
react_1.default.useEffect(() => {
onLoading === null || onLoading === void 0 ? void 0 : onLoading(loading);
}, [loading]);
react_1.default.useEffect(() => {
// 兼容 React 18 StrictMode 开发环境下渲染两次
if (isDevMode && !shouldInit.current) {
return;
}
buildSpreadSheet();
shouldInit.current = false;
return () => {
var _a, _b;
setLoading(false);
(_b = (_a = s2Ref.current) === null || _a === void 0 ? void 0 : _a.destroy) === null || _b === void 0 ? void 0 : _b.call(_a);
};
}, [isDevMode]);
// 重渲 effect:dataCfg, options or theme changed
(0, ahooks_1.useUpdateEffect)(() => {
const render = () => tslib_1.__awaiter(this, void 0, void 0, function* () {
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m;
setLoading(true);
const [prevDataCfg, prevOptions, prevThemeCfg] = updatePrevDepsRef.current;
updatePrevDepsRef.current = [dataCfg, options, themeCfg];
let rerender = false;
let reloadData = false;
let rebuildDataSet = false;
if (!Object.is(prevDataCfg, dataCfg)) {
// 列头变化需要重新计算初始叶子节点
if (((_b = (_a = prevDataCfg === null || prevDataCfg === void 0 ? void 0 : prevDataCfg.fields) === null || _a === void 0 ? void 0 : _a.columns) === null || _b === void 0 ? void 0 : _b.length) !==
((_d = (_c = dataCfg === null || dataCfg === void 0 ? void 0 : dataCfg.fields) === null || _c === void 0 ? void 0 : _c.columns) === null || _d === void 0 ? void 0 : _d.length)) {
(_f = (_e = s2Ref.current) === null || _e === void 0 ? void 0 : _e.facet) === null || _f === void 0 ? void 0 : _f.clearInitColLeafNodes();
}
reloadData = true;
rerender = true;
(_g = s2Ref.current) === null || _g === void 0 ? void 0 : _g.setDataCfg(dataCfg);
}
if (!(0, lodash_1.isEqual)(prevOptions, options)) {
if ((prevOptions === null || prevOptions === void 0 ? void 0 : prevOptions.hierarchyType) !== (options === null || options === void 0 ? void 0 : options.hierarchyType)) {
rebuildDataSet = true;
reloadData = true;
(_h = s2Ref.current) === null || _h === void 0 ? void 0 : _h.setDataCfg(dataCfg);
}
rerender = true;
(_j = s2Ref.current) === null || _j === void 0 ? void 0 : _j.setOptions(options);
(_k = s2Ref.current) === null || _k === void 0 ? void 0 : _k.changeSheetSize(options.width, options.height);
}
if (!(0, lodash_1.isEqual)(prevThemeCfg, themeCfg)) {
rerender = true;
(_l = s2Ref.current) === null || _l === void 0 ? void 0 : _l.setThemeCfg(themeCfg);
}
if (!rerender) {
setLoading(false);
return;
}
/**
* onUpdate 交出控制权
* 由传入方决定最终的 render 模式
*/
const defaultRenderOptions = {
reloadData,
rebuildDataSet,
};
const renderOptions = (onUpdate === null || onUpdate === void 0 ? void 0 : onUpdate(defaultRenderOptions)) || defaultRenderOptions;
yield ((_m = s2Ref.current) === null || _m === void 0 ? void 0 : _m.render(renderOptions));
setLoading(false);
onUpdateAfterRender === null || onUpdateAfterRender === void 0 ? void 0 : onUpdateAfterRender(renderOptions);
});
render();
}, [dataCfg, options, themeCfg, onUpdate]);
(0, useResize_1.useResize)({
s2: s2Ref.current,
container: containerRef.current,
wrapper: wrapperRef.current,
adaptive: props.adaptive,
});
return {
s2Ref,
containerRef,
wrapperRef,
loading,
setLoading,
pagination,
};
}
exports.useSpreadSheet = useSpreadSheet;
//# sourceMappingURL=useSpreadSheet.js.map