fix: upgrade formily & side menu render with createPortal & use deep compare effect (#103)

* [Fixed]
1. ts升级4.4.4
2. 解决升级formily类型不兼容问题

* [Fixed]
1. 修复菜单混合渲染问题

* [Fixed]
1. 修复useEffect对象深度依赖比较(订单表死循环)

* [update]去掉debugger
This commit is contained in:
SemmyWong 2021-11-11 22:07:13 +08:00 committed by GitHub
parent 35739f9f42
commit 686474cb38
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 4962 additions and 4932 deletions

View File

@ -75,6 +75,6 @@
"ts-jest": "^26.5.6", "ts-jest": "^26.5.6",
"ts-node": "^9.1.1", "ts-node": "^9.1.1",
"ts-node-dev": "^1.1.8", "ts-node-dev": "^1.1.8",
"typescript": "4.1.5" "typescript": "4.4.4"
} }
} }

View File

@ -21,9 +21,9 @@
"@antv/g2plot": "^2.3.27", "@antv/g2plot": "^2.3.27",
"@dnd-kit/core": "4.0.0-next-2021720152655", "@dnd-kit/core": "4.0.0-next-2021720152655",
"@dnd-kit/sortable": "5.0.0-next-2021720152655", "@dnd-kit/sortable": "5.0.0-next-2021720152655",
"@formily/antd": "2.0.0-rc.3", "@formily/antd": "2.0.0-rc.19",
"@formily/core": "2.0.0-rc.3", "@formily/core": "2.0.0-rc.19",
"@formily/react": "2.0.0-rc.3", "@formily/react": "2.0.0-rc.19",
"@monaco-editor/react": "^4.2.1", "@monaco-editor/react": "^4.2.1",
"ahooks": "^2.10.2", "ahooks": "^2.10.2",
"axios": "^0.21.1", "axios": "^0.21.1",
@ -39,6 +39,7 @@
"react-helmet": "^6.1.0", "react-helmet": "^6.1.0",
"react-i18next": "^11.12.0", "react-i18next": "^11.12.0",
"react-image-lightbox": "^5.1.4", "react-image-lightbox": "^5.1.4",
"umi-request": "^1.3.5" "umi-request": "^1.3.5",
"use-deep-compare-effect": "^1.8.1"
} }
} }

View File

@ -119,7 +119,7 @@ function LayoutWithMenu(props: LayoutWithMenuProps) {
const sideMenuRef = useRef(); const sideMenuRef = useRef();
const history = useHistory(); const history = useHistory();
const { title } = useSystemSettings(); const { title } = useSystemSettings();
const [activeKey, setActiveKey] = useState(match.params.name); const [activeKey, setActiveKey] = useState('');
const { setPageTitle } = usePageTitleContext(); const { setPageTitle } = usePageTitleContext();
const [selectedKeys, setSelectedKeys] = useState(defaultSelectedKeys); const [selectedKeys, setSelectedKeys] = useState(defaultSelectedKeys);
@ -183,6 +183,7 @@ function LayoutWithMenu(props: LayoutWithMenuProps) {
history.push(`/admin/${uid()}`); history.push(`/admin/${uid()}`);
}; };
console.log({ activeKey, selectedKeys }); console.log({ activeKey, selectedKeys });
return ( return (
<Layout> <Layout>
<Layout.Header className={'site-header'} style={{ display: 'flex' }}> <Layout.Header className={'site-header'} style={{ display: 'flex' }}>

View File

@ -131,7 +131,7 @@ const useArrayTableColumns = (
render: (value: any, record: any) => { render: (value: any, record: any) => {
const index = dataSource.indexOf(record); const index = dataSource.indexOf(record);
const children = ( const children = (
<ArrayBase.Item index={index}> <ArrayBase.Item index={index} record={record}>
<RecursionField schema={schema} name={index} onlyRenderProperties /> <RecursionField schema={schema} name={index} onlyRenderProperties />
</ArrayBase.Item> </ArrayBase.Item>
); );

View File

@ -239,7 +239,7 @@ Filter.DynamicValue = connect((props: DynamicValuePorps) => {
properties: { properties: {
[fieldName]: deepmerge(fieldSchema, extra, { [fieldName]: deepmerge(fieldSchema, extra, {
arrayMerge: (target, source) => source, arrayMerge: (target, source) => source,
}), }) as any,
}, },
}} }}
/> />

View File

@ -4,7 +4,16 @@
import React from 'react'; import React from 'react';
import { SchemaRenderer } from '@nocobase/client'; import { SchemaRenderer } from '@nocobase/client';
import { uid } from '@formily/shared'; import { uid } from '@formily/shared';
import { ISchema } from '@formily/react'; import { ISchema } from '../../index';
type TestSchema = {
[key: `x-${string | number}` | symbol]: any;
};
const a:TestSchema={
'x-232ddd-sd': 'Menu',
'x-key':'dd'
};
const schema: ISchema = { const schema: ISchema = {
type: 'object', type: 'object',

View File

@ -3,7 +3,7 @@
*/ */
import React from 'react'; import React from 'react';
import { SchemaRenderer } from '@nocobase/client'; import { SchemaRenderer } from '@nocobase/client';
import { ISchema } from '@formily/react'; import { ISchema } from '../../index';
const schema: ISchema = { const schema: ISchema = {
type: 'object', type: 'object',

View File

@ -158,34 +158,19 @@ export const Menu: any = observer((props: any) => {
const [selectedKey, setSelectedKey] = useState( const [selectedKey, setSelectedKey] = useState(
defaultSelectedKeys[0] || null, defaultSelectedKeys[0] || null,
); );
const ref = useRef();
const path = useSchemaPath(); const path = useSchemaPath();
const child = schema.properties && schema.properties[selectedKey]; const child = schema.properties && schema.properties[selectedKey];
const isSubMenu = child && child['x-component'] === 'Menu.SubMenu'; const isSubMenu = child && child['x-component'] === 'Menu.SubMenu';
const { updateSchema } = useClient(); const { updateSchema } = useClient();
const { t } = useTranslation(); const { t } = useTranslation();
useMount(() => {
if (mode !== 'mix') {
return;
}
const sideMenuElement = sideMenuRef && (sideMenuRef.current as HTMLElement);
if (!sideMenuElement) {
return;
}
if (sideMenuElement && ref.current) {
sideMenuElement.querySelector(':scope > div').appendChild(ref.current);
}
sideMenuElement.style.display = isSubMenu ? 'block' : 'none';
});
useEffect(() => { useEffect(() => {
const sideMenuElement = sideMenuRef && (sideMenuRef.current as HTMLElement); const sideMenuElement = sideMenuRef && (sideMenuRef.current as HTMLElement);
if (!sideMenuElement) { if (!sideMenuElement) {
return; return;
} }
sideMenuElement.style.display = isSubMenu ? 'block' : 'none'; sideMenuElement.style.display = isSubMenu ? 'block' : 'none';
}, [selectedKey]); }, [selectedKey, sideMenuRef]);
const [dragOverlayContent, setDragOverlayContent] = useState(''); const [dragOverlayContent, setDragOverlayContent] = useState('');
// console.log('defaultSelectedKeys', defaultSelectedKeys, getSelectedKeys); // console.log('defaultSelectedKeys', defaultSelectedKeys, getSelectedKeys);
@ -246,8 +231,9 @@ export const Menu: any = observer((props: any) => {
</Button> </Button>
</Menu.AddNew> </Menu.AddNew>
</AntdMenu> </AntdMenu>
{mode === 'mix' && ( {mode === 'mix' &&
<div ref={ref}> sideMenuRef.current?.firstChild &&
createPortal(
<SideMenu <SideMenu
path={path} path={path}
onSelect={(info) => { onSelect={(info) => {
@ -260,9 +246,9 @@ export const Menu: any = observer((props: any) => {
defaultSelectedKeys={defaultSelectedKeys || []} defaultSelectedKeys={defaultSelectedKeys || []}
selectedKey={selectedKey} selectedKey={selectedKey}
sideMenuRef={sideMenuRef} sideMenuRef={sideMenuRef}
/> />,
</div> sideMenuRef.current.firstChild,
)} )}
</MenuModeContext.Provider> </MenuModeContext.Provider>
</DndContext> </DndContext>
</MenuContext.Provider> </MenuContext.Provider>
@ -746,7 +732,10 @@ Menu.DesignableBar = (props) => {
return; return;
} }
const values = await FormDialog( const values = await FormDialog(
t(`Add {{type}} ${methodLabels[method]} "{{title}}"`, { type: (config.title as string).toLowerCase(), title: schema.title }), t(`Add {{type}} ${methodLabels[method]} "{{title}}"`, {
type: (config.title as string).toLowerCase(),
title: schema.title,
}),
// `在「${schema.title}」${methodLabels[method]}插入${config.title}`, // `在「${schema.title}」${methodLabels[method]}插入${config.title}`,
() => { () => {
return ( return (
@ -862,8 +851,14 @@ Menu.DesignableBar = (props) => {
type: 'string', type: 'string',
default: 'insertAfter', default: 'insertAfter',
enum: [ enum: [
{ label: t('After'), value: 'insertAfter' }, {
{ label: t('Before'), value: 'insertBefore' }, label: t('After'),
value: 'insertAfter',
},
{
label: t('Before'),
value: 'insertBefore',
},
], ],
'x-decorator': 'FormItem', 'x-decorator': 'FormItem',
'x-component': 'Radio.Group', 'x-component': 'Radio.Group',
@ -891,12 +886,18 @@ Menu.DesignableBar = (props) => {
target['x-component'] === 'Menu.SubMenu' target['x-component'] === 'Menu.SubMenu'
? [ ? [
{ label: t('After'), value: 'insertAfter' }, { label: t('After'), value: 'insertAfter' },
{ label: t('Before'), value: 'insertBefore' }, {
label: t('Before'),
value: 'insertBefore',
},
{ label: t('Inner'), value: 'appendChild' }, { label: t('Inner'), value: 'appendChild' },
] ]
: [ : [
{ label: t('After'), value: 'insertAfter' }, { label: t('After'), value: 'insertAfter' },
{ label: t('Before'), value: 'insertBefore' }, {
label: t('Before'),
value: 'insertBefore',
},
]; ];
}); });
}); });

View File

@ -11,6 +11,7 @@ import { cloneDeep, cloneDeepWith, findIndex, forIn, range, set } from 'lodash';
import React, { Fragment, useEffect, useState } from 'react'; import React, { Fragment, useEffect, useState } from 'react';
import { useContext } from 'react'; import { useContext } from 'react';
import { createContext } from 'react'; import { createContext } from 'react';
import { useDeepCompareEffectNoCheck } from 'use-deep-compare-effect';
import { useDesignable, createCollectionField, ISchema } from '..'; import { useDesignable, createCollectionField, ISchema } from '..';
import { uid, merge } from '@formily/shared'; import { uid, merge } from '@formily/shared';
import useRequest from '@ahooksjs/use-request'; import useRequest from '@ahooksjs/use-request';
@ -905,7 +906,7 @@ const TableProvider = (props: any) => {
// defaultParams: [getDefaultParams()], // defaultParams: [getDefaultParams()],
}, },
); );
useEffect(() => { useDeepCompareEffectNoCheck(() => {
service.run(getDefaultParams()); service.run(getDefaultParams());
}, [ }, [
pagination?.pageSize, pagination?.pageSize,

View File

@ -61,7 +61,7 @@
"temp-dir": "2.0.0", "temp-dir": "2.0.0",
"through2": "3.0.1", "through2": "3.0.1",
"ts-loader": "^8.0.7", "ts-loader": "^8.0.7",
"typescript": "4.1.5", "typescript": "4.4.4",
"update-notifier": "3.0.0", "update-notifier": "3.0.0",
"vinyl-fs": "3.0.3", "vinyl-fs": "3.0.3",
"yargs-parser": "13.1.2" "yargs-parser": "13.1.2"

View File

@ -13,6 +13,7 @@
"declaration": true, "declaration": true,
"experimentalDecorators": true, "experimentalDecorators": true,
"downlevelIteration": true, "downlevelIteration": true,
"skipLibCheck": true,
"baseUrl": ".", "baseUrl": ".",
"paths": { "paths": {
"@nocobase/*": [ "@nocobase/*": [
@ -20,4 +21,4 @@
] ]
} }
} }
} }

9802
yarn.lock

File diff suppressed because it is too large Load Diff