diff --git a/.eslintrc.js b/.eslintrc.js index 919faddf06..088f34d17e 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -78,6 +78,8 @@ module.exports = { 'jsx-a11y/href-no-hash': 0, 'jsx-a11y/control-has-associated-label': 0, 'import/no-extraneous-dependencies': 0, + 'react/jsx-no-constructed-context-values': 0, + 'react/no-unstable-nested-components': 0, }, }, ], @@ -100,7 +102,8 @@ module.exports = { 'react/no-unused-prop-types': 0, 'react/default-props-match-prop-types': 0, 'react-hooks/rules-of-hooks': 2, // Checks rules of Hooks - + 'react/function-component-definition': 0, + 'react/no-unused-class-component-methods': 0, 'import/extensions': 0, 'import/no-cycle': 0, 'import/no-extraneous-dependencies': [ diff --git a/components/_util/__tests__/unreachableException.test.js b/components/_util/__tests__/unreachableException.test.js index f7620f1b16..4019e4fedc 100644 --- a/components/_util/__tests__/unreachableException.test.js +++ b/components/_util/__tests__/unreachableException.test.js @@ -3,6 +3,6 @@ import UnreachableException from '../unreachableException'; describe('UnreachableException', () => { it('error thrown matches snapshot', () => { const exception = new UnreachableException('some value'); - expect(exception.message).toMatchInlineSnapshot(`"unreachable case: \\"some value\\""`); + expect(exception.error.message).toMatchInlineSnapshot(`"unreachable case: \\"some value\\""`); }); }); diff --git a/components/_util/unreachableException.ts b/components/_util/unreachableException.ts index ea10deade7..baaf8c8243 100644 --- a/components/_util/unreachableException.ts +++ b/components/_util/unreachableException.ts @@ -1,5 +1,8 @@ + export default class UnreachableException { + error: Error; + constructor(value: never) { - return new Error(`unreachable case: ${JSON.stringify(value)}`); + this.error = new Error(`unreachable case: ${JSON.stringify(value)}`); } } diff --git a/components/anchor/Anchor.tsx b/components/anchor/Anchor.tsx index 491a92eebf..792251bb3e 100644 --- a/components/anchor/Anchor.tsx +++ b/components/anchor/Anchor.tsx @@ -1,5 +1,6 @@ import * as React from 'react'; import classNames from 'classnames'; +import memoizeOne from 'memoize-one'; import addEventListener from 'rc-util/lib/Dom/addEventListener'; import Affix from '../affix'; import AnchorLink from './AnchorLink'; @@ -258,7 +259,6 @@ export default class Anchor extends React.Component ); + const contextValue = memoizeOne((link, onClickFn) => ({ + registerLink: this.registerLink, + unregisterLink: this.unregisterLink, + scrollTo: this.handleScrollTo, + activeLink: link, + onClick: onClickFn, + }))(activeLink, onClick); + return ( - + {!affix ? ( anchorContent ) : ( diff --git a/components/breadcrumb/Breadcrumb.tsx b/components/breadcrumb/Breadcrumb.tsx index bcf0051f16..c5f35ba3f0 100755 --- a/components/breadcrumb/Breadcrumb.tsx +++ b/components/breadcrumb/Breadcrumb.tsx @@ -55,9 +55,9 @@ const getPath = (path: string, params: any) => { return path; }; -const addChildPath = (paths: string[], childPath: string = '', params: any) => { +const addChildPath = (paths: string[], childPath: string, params: any) => { const originalPaths = [...paths]; - const path = getPath(childPath, params); + const path = getPath(childPath || '', params); if (path) { originalPaths.push(path); } diff --git a/components/button/__tests__/index.test.tsx b/components/button/__tests__/index.test.tsx index 9faacc8670..265c654228 100644 --- a/components/button/__tests__/index.test.tsx +++ b/components/button/__tests__/index.test.tsx @@ -316,6 +316,7 @@ describe('Button', () => { it('should handle fragment as children', () => { const wrapper = mount( , ); diff --git a/components/button/button-group.tsx b/components/button/button-group.tsx index d8e0cf20cd..c9e74d44db 100644 --- a/components/button/button-group.tsx +++ b/components/button/button-group.tsx @@ -32,7 +32,7 @@ const ButtonGroup: React.FC = props => ( break; default: // eslint-disable-next-line no-console - console.warn(new UnreachableException(size)); + console.warn((new UnreachableException(size)).error); } const classes = classNames( diff --git a/components/carousel/__tests__/index.test.js b/components/carousel/__tests__/index.test.js index e799ee4581..0ad98a69a5 100644 --- a/components/carousel/__tests__/index.test.js +++ b/components/carousel/__tests__/index.test.js @@ -3,6 +3,7 @@ import { mount } from 'enzyme'; import Carousel from '..'; import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; +import { sleep } from '../../../tests/utils'; describe('Carousel', () => { mountTest(Carousel); @@ -65,7 +66,7 @@ describe('Carousel', () => { const spy = jest.spyOn(ref.current.innerSlider, 'autoPlay'); window.resizeTo(1000); expect(spy).not.toHaveBeenCalled(); - await new Promise(resolve => setTimeout(resolve, 500)); + await sleep(500); expect(spy).toHaveBeenCalled(); }); diff --git a/components/checkbox/Group.tsx b/components/checkbox/Group.tsx index 45bc5d24a8..360bc08d1d 100644 --- a/components/checkbox/Group.tsx +++ b/components/checkbox/Group.tsx @@ -131,17 +131,16 @@ const InternalCheckboxGroup: React.ForwardRefRenderFunction ({ labelStyle, contentStyle }), [labelStyle, contentStyle]); return ( - +
= pro ) : null; // Pass to sub FormItem should not with col info - const subFormContext = { ...formContext }; + const subFormContext = React.useMemo(() => ({ ...formContext }), [formContext]); delete subFormContext.labelCol; delete subFormContext.wrapperCol; @@ -87,8 +87,9 @@ const FormItemInput: React.FC = pro {icon}
); + const formItemContext = React.useMemo(() => ({ prefixCls, status }), [prefixCls, status]); const errorListDom = ( - + = ({ const { getPrefixCls } = React.useContext(ConfigContext); const prefixCls = getPrefixCls('form', customizePrefixCls); + const contextValue = React.useMemo( + () => ({ + prefixCls, + status: 'error' as const, + }), + [prefixCls], + ); return ( {(fields, operation, meta) => ( - + {children( fields.map(field => ({ ...field, fieldKey: field.key })), operation, diff --git a/components/form/demo/form-context.md b/components/form/demo/form-context.md index f03c26f536..4050952d09 100644 --- a/components/form/demo/form-context.md +++ b/components/form/demo/form-context.md @@ -94,56 +94,54 @@ const Demo = () => { }; return ( - <> - { - if (name === 'userForm') { - const { basicForm } = forms; - const users = basicForm.getFieldValue('users') || []; - basicForm.setFieldsValue({ users: [...users, values] }); - setVisible(false); - } - }} - > -
- - - - prevValues.users !== curValues.users} - > - {({ getFieldValue }) => { - const users: UserType[] = getFieldValue('users') || []; - return users.length ? ( -
    - {users.map((user, index) => ( -
  • - } /> - {user.name} - {user.age} -
  • - ))} -
- ) : ( - - ( No user yet. ) - - ); - }} -
- - - - -
- - -
- + { + if (name === 'userForm') { + const { basicForm } = forms; + const users = basicForm.getFieldValue('users') || []; + basicForm.setFieldsValue({ users: [...users, values] }); + setVisible(false); + } + }} + > +
+ + + + prevValues.users !== curValues.users} + > + {({ getFieldValue }) => { + const users: UserType[] = getFieldValue('users') || []; + return users.length ? ( +
    + {users.map((user, index) => ( +
  • + } /> + {user.name} - {user.age} +
  • + ))} +
+ ) : ( + + ( No user yet. ) + + ); + }} +
+ + + + +
+ + +
); }; diff --git a/components/form/demo/layout.md b/components/form/demo/layout.md index b15361faa1..07a9b23c62 100644 --- a/components/form/demo/layout.md +++ b/components/form/demo/layout.md @@ -43,32 +43,30 @@ const FormLayoutDemo = () => { : null; return ( - <> -
- - - Horizontal - Vertical - Inline - - - - - - - - - - - -
- +
+ + + Horizontal + Vertical + Inline + + + + + + + + + + + +
); }; diff --git a/components/form/demo/size.md b/components/form/demo/size.md index 420b11b616..43290281b6 100644 --- a/components/form/demo/size.md +++ b/components/form/demo/size.md @@ -36,67 +36,65 @@ const FormSizeDemo = () => { setComponentSize(size); }; return ( - <> -
- - - Small - Default - Large - - - - - - - - - - - - - - - - - - - - - - - - - - -
- +
+ + + Small + Default + Large + + + + + + + + + + + + + + + + + + + + + + + + + + +
); }; diff --git a/components/layout/Sider.tsx b/components/layout/Sider.tsx index e05b0efec0..01ac838d41 100644 --- a/components/layout/Sider.tsx +++ b/components/layout/Sider.tsx @@ -214,15 +214,14 @@ const Sider = React.forwardRef( ); }; - return ( - - {renderSider()} - + const contextValue = React.useMemo( + () => ({ + siderCollapsed: collapsed, + }), + [collapsed], ); + + return {renderSider()}; }, ); diff --git a/components/layout/layout.tsx b/components/layout/layout.tsx index ad8665f84f..f9a3b0c088 100644 --- a/components/layout/layout.tsx +++ b/components/layout/layout.tsx @@ -64,19 +64,22 @@ const BasicLayout: React.FC = props => { className, ); - return ( - { - setSiders(prev => [...prev, id]); - }, - removeSider: (id: string) => { - setSiders(prev => prev.filter(currentId => currentId !== id)); - }, + const contextValue = React.useMemo( + () => ({ + siderHook: { + addSider: (id: string) => { + setSiders(prev => [...prev, id]); + }, + removeSider: (id: string) => { + setSiders(prev => prev.filter(currentId => currentId !== id)); }, - }} - > + }, + }), + [], + ); + + return ( + {children} diff --git a/components/list/demo/grid-test.md b/components/list/demo/grid-test.md index 50bf67ccdc..ba1e05fee8 100644 --- a/components/list/demo/grid-test.md +++ b/components/list/demo/grid-test.md @@ -50,11 +50,9 @@ ReactDOM.render( grid={{ gutter: 16, column: 4 }} dataSource={data} renderItem={item => ( - <> - - Card content - - + + Card content + )} /> } /> diff --git a/components/list/index.tsx b/components/list/index.tsx index 717dd58a71..ca6b174bb3 100644 --- a/components/list/index.tsx +++ b/components/list/index.tsx @@ -256,9 +256,13 @@ function List({ } const paginationPosition = paginationProps.position || 'bottom'; + const contextValue = React.useMemo( + () => ({ grid, itemLayout }), + [JSON.stringify(grid), itemLayout], + ); return ( - +
{(paginationPosition === 'top' || paginationPosition === 'both') && paginationContent} {header &&
{header}
} diff --git a/components/locale-provider/index.tsx b/components/locale-provider/index.tsx index 6731d20d6c..e7ce697287 100644 --- a/components/locale-provider/index.tsx +++ b/components/locale-provider/index.tsx @@ -1,4 +1,5 @@ import * as React from 'react'; +import memoizeOne from 'memoize-one'; import { ValidateMessages } from 'rc-field-form/lib/interface'; import devWarning from '../_util/devWarning'; @@ -79,9 +80,10 @@ export default class LocaleProvider extends React.Component{children} - ); + const contextValue = memoizeOne(localeValue => ({ + ...localeValue, + exist: true, + }))(locale); + return {children}; } } diff --git a/components/mentions/__tests__/index.test.js b/components/mentions/__tests__/index.test.js index d95963881c..46c04a1f7a 100644 --- a/components/mentions/__tests__/index.test.js +++ b/components/mentions/__tests__/index.test.js @@ -7,7 +7,7 @@ import rtlTest from '../../../tests/shared/rtlTest'; const { getMentions } = Mentions; -function simulateInput(wrapper, text = '', keyEvent) { +function simulateInput(wrapper, text, keyEvent) { const lastChar = text[text.length - 1]; const myKeyEvent = keyEvent || { which: lastChar.charCodeAt(0), diff --git a/components/mentions/index.tsx b/components/mentions/index.tsx index 2936f31ca7..aa2e3d97b3 100644 --- a/components/mentions/index.tsx +++ b/components/mentions/index.tsx @@ -137,8 +137,8 @@ const Mentions = React.forwardRef(InternalMentions) as Co Mentions.displayName = 'Mentions'; Mentions.Option = Option; -Mentions.getMentions = (value: string = '', config?: MentionsConfig): MentionsEntity[] => { - const { prefix = '@', split = ' ' } = config || {}; +Mentions.getMentions = (value: string = '', config: MentionsConfig = {}): MentionsEntity[] => { + const { prefix = '@', split = ' ' } = config; const prefixList: string[] = Array.isArray(prefix) ? prefix : [prefix]; return value diff --git a/components/menu/SubMenu.tsx b/components/menu/SubMenu.tsx index acb9a750e0..6268b5cd79 100644 --- a/components/menu/SubMenu.tsx +++ b/components/menu/SubMenu.tsx @@ -58,13 +58,16 @@ function SubMenu(props: SubMenuProps) { ); } + const contextValue = React.useMemo( + () => ({ + ...context, + firstLevel: false, + }), + [context], + ); + return ( - + { {null} + {/* eslint-disable-next-line react/jsx-no-useless-fragment */} <> {undefined} + {/* eslint-disable-next-line react/jsx-no-useless-fragment */} <> + {/* eslint-disable-next-line react/jsx-no-useless-fragment */} <> diff --git a/components/menu/index.tsx b/components/menu/index.tsx index 716b8f4acd..28fac6e9cb 100644 --- a/components/menu/index.tsx +++ b/components/menu/index.tsx @@ -3,6 +3,7 @@ import RcMenu, { ItemGroup, MenuProps as RcMenuProps } from 'rc-menu'; import classNames from 'classnames'; import omit from 'rc-util/lib/omit'; import EllipsisOutlined from '@ant-design/icons/EllipsisOutlined'; +import memoize from 'memoize-one'; import SubMenu, { SubMenuProps } from './SubMenu'; import Item, { MenuItemProps } from './MenuItem'; import { ConfigConsumer, ConfigConsumerProps } from '../config-provider'; @@ -81,16 +82,17 @@ class InternalMenu extends React.Component { const prefixCls = getPrefixCls('menu', customizePrefixCls); const menuClassName = classNames(`${prefixCls}-${theme}`, className); + // TODO: refactor menu with function component + const contextValue = memoize((cls, collapsed, the, dir) => ({ + prefixCls: cls, + inlineCollapsed: collapsed || false, + antdMenuTheme: the, + direction: dir, + firstLevel: true, + }))(prefixCls, inlineCollapsed, theme, direction); + return ( - + } diff --git a/components/modal/demo/modal-render.md b/components/modal/demo/modal-render.md index 6def9a98aa..8a5ef97571 100644 --- a/components/modal/demo/modal-render.md +++ b/components/modal/demo/modal-render.md @@ -47,14 +47,17 @@ class App extends React.Component { }; onStart = (event, uiData) => { - const { clientWidth, clientHeight } = window?.document?.documentElement; - const targetRect = this.draggleRef?.current?.getBoundingClientRect(); + const { clientWidth, clientHeight } = window.document.documentElement; + const targetRect = this.draggleRef.current?.getBoundingClientRect(); + if (!targetRect) { + return; + } this.setState({ bounds: { - left: -targetRect?.left + uiData?.x, - right: clientWidth - (targetRect?.right - uiData?.x), - top: -targetRect?.top + uiData?.y, - bottom: clientHeight - (targetRect?.bottom - uiData?.y), + left: -targetRect.left + uiData.x, + right: clientWidth - (targetRect.right - uiData.x), + top: -targetRect.top + uiData.y, + bottom: clientHeight - (targetRect.bottom - uiData.y), }, }); }; diff --git a/components/modal/useModal/index.tsx b/components/modal/useModal/index.tsx index 7408989711..a2aa0e8382 100644 --- a/components/modal/useModal/index.tsx +++ b/components/modal/useModal/index.tsx @@ -27,6 +27,7 @@ const ElementsHolder = React.memo( }), [], ); + // eslint-disable-next-line react/jsx-no-useless-fragment return <>{elements}; }), ); diff --git a/components/page-header/demo/responsive.md b/components/page-header/demo/responsive.md index 5233f5e3ac..3812aa8200 100644 --- a/components/page-header/demo/responsive.md +++ b/components/page-header/demo/responsive.md @@ -60,29 +60,27 @@ const Content = ({ children, extra }) => ( ); ReactDOM.render( - <> - window.history.back()} - title="Title" - subTitle="This is a subtitle" - extra={[ - , - , - , - ]} - footer={ - - - - - } - > - {renderContent()} - - , + window.history.back()} + title="Title" + subTitle="This is a subtitle" + extra={[ + , + , + , + ]} + footer={ + + + + + } + > + {renderContent()} + , mountNode, ); ``` diff --git a/components/pagination/demo/all.md b/components/pagination/demo/all.md index bd9ce4a549..5fd4165416 100644 --- a/components/pagination/demo/all.md +++ b/components/pagination/demo/all.md @@ -17,14 +17,12 @@ Show all configured prop. import { Pagination } from 'antd'; ReactDOM.render( - <> - `Total ${total} items`} - /> - , + `Total ${total} items`} + />, mountNode, ); ``` diff --git a/components/popconfirm/__tests__/index.test.js b/components/popconfirm/__tests__/index.test.js index 20e0332849..5d8da7681a 100644 --- a/components/popconfirm/__tests__/index.test.js +++ b/components/popconfirm/__tests__/index.test.js @@ -132,7 +132,7 @@ describe('Popconfirm', () => { }); it('should support onConfirm to return Promise', async () => { - const confirm = () => new Promise(res => setTimeout(res, 300)); + const confirm = () => new Promise(res => { setTimeout(res, 300); }); const onVisibleChange = jest.fn(); const popconfirm = mount( diff --git a/components/popconfirm/demo/async.md b/components/popconfirm/demo/async.md index a7f65a6bf9..823417f97c 100644 --- a/components/popconfirm/demo/async.md +++ b/components/popconfirm/demo/async.md @@ -38,19 +38,17 @@ const App = () => { }; return ( - <> - - - - + + + ); }; diff --git a/components/space/__tests__/index.test.js b/components/space/__tests__/index.test.js index b7cff19757..daa8aedcf2 100644 --- a/components/space/__tests__/index.test.js +++ b/components/space/__tests__/index.test.js @@ -97,6 +97,7 @@ describe('Space', () => { const wrapper = mount( text1text1 + {/* eslint-disable-next-line react/jsx-no-useless-fragment */} <>text3 , ); @@ -164,6 +165,7 @@ describe('Space', () => { const wrapper = mount( text1text1 + {/* eslint-disable-next-line react/jsx-no-useless-fragment */} <>text3 , ); diff --git a/components/spin/__tests__/delay.test.js b/components/spin/__tests__/delay.test.js index bdeb570433..fbee446e7c 100644 --- a/components/spin/__tests__/delay.test.js +++ b/components/spin/__tests__/delay.test.js @@ -1,6 +1,7 @@ import React from 'react'; import { mount } from 'enzyme'; import Spin from '..'; +import { sleep } from '../../../tests/utils'; describe('delay spinning', () => { it("should render with delay when it's mounted with spinning=true and delay", () => { @@ -15,7 +16,7 @@ describe('delay spinning', () => { // use await not jest.runAllTimers() // because of https://github.com/facebook/jest/issues/3465 - await new Promise(resolve => setTimeout(resolve, 500)); + await sleep(500); wrapper.update(); expect(wrapper.find('.ant-spin').at(0).hasClass('ant-spin-spinning')).toEqual(true); diff --git a/components/switch/__tests__/index.test.js b/components/switch/__tests__/index.test.js index e96a669f6d..0840369aac 100644 --- a/components/switch/__tests__/index.test.js +++ b/components/switch/__tests__/index.test.js @@ -5,6 +5,7 @@ import focusTest from '../../../tests/shared/focusTest'; import { resetWarned } from '../../_util/devWarning'; import mountTest from '../../../tests/shared/mountTest'; import rtlTest from '../../../tests/shared/rtlTest'; +import { sleep } from '../../../tests/utils'; describe('Switch', () => { focusTest(Switch, { refFocus: true }); @@ -14,7 +15,7 @@ describe('Switch', () => { it('should has click wave effect', async () => { const wrapper = mount(); wrapper.find('.ant-switch').getDOMNode().click(); - await new Promise(resolve => setTimeout(resolve, 0)); + await sleep(0); expect(wrapper.find('button').getDOMNode().getAttribute('ant-click-animating')).toBe('true'); }); diff --git a/components/table/__tests__/Table.filter.test.js b/components/table/__tests__/Table.filter.test.js index df68745c5c..9aeeed49d4 100644 --- a/components/table/__tests__/Table.filter.test.js +++ b/components/table/__tests__/Table.filter.test.js @@ -866,6 +866,7 @@ describe('Table.filter', () => { dataIndex: 'name', key: 'name', filteredValue: name, + // eslint-disable-next-line react/no-unstable-nested-components filterDropdown: ({ setSelectedKeys, selectedKeys, confirm }) => (
{ cols: [], }; - componentDidMount = () => { + componentDidMount() { this.setState({ cols: [ { @@ -1276,7 +1277,7 @@ describe('Table.filter', () => { }, ], }); - }; + } render() { const { cols } = this.state; @@ -1700,38 +1701,36 @@ describe('Table.filter', () => { }, ]; return ( - <> - - +
); } } diff --git a/components/table/demo/edit-row.md b/components/table/demo/edit-row.md index c07f2eb2ee..eacf65c0f3 100644 --- a/components/table/demo/edit-row.md +++ b/components/table/demo/edit-row.md @@ -145,9 +145,9 @@ const EditableTable = () => { const editable = isEditing(record); return editable ? ( - save(record.key)} style={{ marginRight: 8 }}> + save(record.key)} style={{ marginRight: 8 }}> Save - + Cancel diff --git a/components/table/hooks/usePagination.ts b/components/table/hooks/usePagination.ts index 029ab946f0..7997877580 100644 --- a/components/table/hooks/usePagination.ts +++ b/components/table/hooks/usePagination.ts @@ -75,9 +75,9 @@ export default function usePagination( mergedPagination.current = maxPage || 1; } - const refreshPagination = (current: number = 1, pageSize?: number) => { + const refreshPagination = (current?: number, pageSize?: number) => { setInnerPagination({ - current, + current: current ?? 1, pageSize: pageSize || mergedPagination.pageSize, }); }; diff --git a/components/timeline/__tests__/index.test.js b/components/timeline/__tests__/index.test.js index 1c4ea9ab38..de9471c756 100644 --- a/components/timeline/__tests__/index.test.js +++ b/components/timeline/__tests__/index.test.js @@ -6,7 +6,7 @@ import rtlTest from '../../../tests/shared/rtlTest'; const { Item } = TimeLine; -const wrapperFactory = (timeLineProps = {}, labelItems) => +const wrapperFactory = (timeLineProps = {}, labelItems = null) => mount( foo diff --git a/components/typography/__tests__/index.test.js b/components/typography/__tests__/index.test.js index 1e289d04b6..e4f3158bdf 100644 --- a/components/typography/__tests__/index.test.js +++ b/components/typography/__tests__/index.test.js @@ -395,7 +395,7 @@ describe('Typography', () => { }); describe('editable', () => { - function testStep({ name = '', icon, tooltip } = {}, submitFunc, expectFunc) { + function testStep({ name, icon, tooltip }, submitFunc, expectFunc) { it(name, () => { jest.useFakeTimers(); const onStart = jest.fn(); diff --git a/components/upload/__tests__/upload.test.js b/components/upload/__tests__/upload.test.js index a29901327c..8eb648d13a 100644 --- a/components/upload/__tests__/upload.test.js +++ b/components/upload/__tests__/upload.test.js @@ -52,7 +52,7 @@ describe('Upload', () => { const data = jest.fn(); const props = { action: 'http://upload.com', - beforeUpload: () => new Promise(resolve => setTimeout(() => resolve('success'), 100)), + beforeUpload: () => new Promise(resolve => { setTimeout(() => resolve('success'), 100); }), data, onChange: ({ file }) => { if (file.status !== 'uploading') { @@ -103,13 +103,13 @@ describe('Upload', () => { const props = { action: 'http://upload.com', beforeUpload: file => - new Promise(resolve => + new Promise(resolve => { setTimeout(() => { const result = file; result.name = 'test.png'; resolve(result); - }, 100), - ), + }, 100); + }), data, onChange: ({ file }) => { if (file.status !== 'uploading') { diff --git a/components/upload/demo/transform-file.md b/components/upload/demo/transform-file.md index 4672177e75..40b394033a 100644 --- a/components/upload/demo/transform-file.md +++ b/components/upload/demo/transform-file.md @@ -45,11 +45,9 @@ const props = { }; ReactDOM.render( - <> - - - - , + + + , mountNode, ); ``` diff --git a/package.json b/package.json index f211bc6fa4..5a9008c506 100644 --- a/package.json +++ b/package.json @@ -119,6 +119,7 @@ "classnames": "^2.2.6", "copy-to-clipboard": "^3.2.0", "lodash": "^4.17.21", + "memoize-one": "^6.0.0", "moment": "^2.25.3", "rc-cascader": "~2.2.0", "rc-checkbox": "~2.3.0", @@ -199,7 +200,7 @@ "enzyme-to-json": "^3.6.0", "esbuild-loader": "^2.13.1", "eslint": "^8.0.0", - "eslint-config-airbnb": "^18.0.0", + "eslint-config-airbnb": "^19.0.0", "eslint-config-prettier": "^8.0.0", "eslint-plugin-babel": "^5.3.0", "eslint-plugin-compat": "^4.0.0", diff --git a/site/theme/template/Content/Demo/CodePenIcon.jsx b/site/theme/template/Content/Demo/CodePenIcon.jsx index 7a26b5809d..53a08e6343 100644 --- a/site/theme/template/Content/Demo/CodePenIcon.jsx +++ b/site/theme/template/Content/Demo/CodePenIcon.jsx @@ -1,13 +1,12 @@ import React from 'react'; import Icon from '@ant-design/icons'; -const CodePenIcon = props => { - const SVGIcon = () => ( - - - - ); - return ; -}; +const SVGIcon = () => ( + + + +); + +const CodePenIcon = props => ; export default CodePenIcon; diff --git a/site/theme/template/Content/Demo/CodeSandboxIcon.jsx b/site/theme/template/Content/Demo/CodeSandboxIcon.jsx index 7857f98109..67ad6edabb 100644 --- a/site/theme/template/Content/Demo/CodeSandboxIcon.jsx +++ b/site/theme/template/Content/Demo/CodeSandboxIcon.jsx @@ -1,13 +1,12 @@ import React from 'react'; import Icon from '@ant-design/icons'; -const CodeSandboxIcon = props => { - const SVGIcon = () => ( - - - - ); - return ; -}; +const SVGIcon = () => ( + + + +); + +const CodeSandboxIcon = props => ; export default CodeSandboxIcon; diff --git a/site/theme/template/Content/Demo/RiddleIcon.jsx b/site/theme/template/Content/Demo/RiddleIcon.jsx index 044e7d5ea2..76b5dcf0ff 100644 --- a/site/theme/template/Content/Demo/RiddleIcon.jsx +++ b/site/theme/template/Content/Demo/RiddleIcon.jsx @@ -1,13 +1,12 @@ import React from 'react'; import Icon from '@ant-design/icons'; -const RiddleIcon = props => { - const SVGIcon = () => ( - - - - ); - return ; -}; +const SVGIcon = () => ( + + + +); + +const RiddleIcon = props => ; export default RiddleIcon; diff --git a/site/theme/template/Content/ThemeIcon.jsx b/site/theme/template/Content/ThemeIcon.jsx index 563056580d..ab6fa78acf 100644 --- a/site/theme/template/Content/ThemeIcon.jsx +++ b/site/theme/template/Content/ThemeIcon.jsx @@ -2,7 +2,7 @@ import React from 'react'; import Icon from '@ant-design/icons'; const ThemeIcon = props => { - const SVGIcon = () => ( + const SVGIcon = React.useCallback(() => ( @@ -10,7 +10,7 @@ const ThemeIcon = props => { - ); + ), [props]); return ; }; diff --git a/site/theme/template/Home/index.tsx b/site/theme/template/Home/index.tsx index 827eade91e..1296a04a9c 100644 --- a/site/theme/template/Home/index.tsx +++ b/site/theme/template/Home/index.tsx @@ -52,7 +52,7 @@ const Home = (props: { location: any }) => { zhCN: '文章', enUS: 'Articles', }); - const { pathname, query } = path; + const { pathname, query = {} } = path; const pathnames = pathname.split('#'); if ('direction' in query) { return `${pathnames[0]}?direction=rtl#${pathnames[1]}`; diff --git a/site/theme/template/IconDisplay/index.tsx b/site/theme/template/IconDisplay/index.tsx index a3234cb943..73ada041f0 100644 --- a/site/theme/template/IconDisplay/index.tsx +++ b/site/theme/template/IconDisplay/index.tsx @@ -64,6 +64,7 @@ class IconDisplay extends React.PureComponent$`, 'gi'), (_, name) => name) .replace(/(Filled|Outlined|TwoTone)$/, '') .toLowerCase(); diff --git a/site/theme/template/Layout/Footer.tsx b/site/theme/template/Layout/Footer.tsx index e8e01753dc..d240871d80 100644 --- a/site/theme/template/Layout/Footer.tsx +++ b/site/theme/template/Layout/Footer.tsx @@ -35,7 +35,7 @@ class Footer extends React.Component const getLinkHash = (path: string, hash: { zhCN: string; enUS: string }) => { const pathName = getLocalizedPathname(path, isZhCN, location.query, hash); - const { pathname, query } = pathName; + const { pathname, query = {} } = pathName; const pathnames = pathname.split('#'); if ('direction' in query) { return `${pathnames[0]}?direction=rtl#${pathnames[1]}`; @@ -45,7 +45,7 @@ class Footer extends React.Component const getLink = (path: string) => { const pathName = getLocalizedPathname(path, isZhCN, location.query); - const { pathname, query } = pathName; + const { pathname, query = {} } = pathName; if ('direction' in query) { return `${pathname}?direction=rtl}`; } diff --git a/site/theme/template/utils.tsx b/site/theme/template/utils.tsx index 049801785f..73704ea823 100644 --- a/site/theme/template/utils.tsx +++ b/site/theme/template/utils.tsx @@ -118,10 +118,10 @@ export function isZhCN(pathname: string) { export function getLocalizedPathname( path: string, zhCN?: boolean, - query = {}, + query?: { [key: string]: any }, hash?: { - zhCN: string; - enUS: string; + zhCN?: string; + enUS?: string; }, ) { const pathname = path.startsWith('/') ? path : `/${path}`; diff --git a/tests/utils.ts b/tests/utils.ts index a81065cf7a..7a6877b484 100644 --- a/tests/utils.ts +++ b/tests/utils.ts @@ -13,6 +13,6 @@ const globalTimeout = global.setTimeout; export const sleep = async (timeout = 0) => { await act(async () => { - await new Promise(resolve => globalTimeout(resolve, timeout)); + await new Promise(resolve => { globalTimeout(resolve, timeout); }); }); };