Browse Source

refactoring: use React.createRef replace ref function (#40538)

* style: use React.createRef replace ref function

* style: use React.createRef replace ref function

* add useRef

* fix

* rename
pull/40549/head
lijianan 2 years ago
committed by GitHub
parent
commit
0a75cfe9e2
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 47
      components/affix/index.tsx
  2. 13
      components/button/__tests__/index.test.tsx
  3. 3
      components/calendar/index.ts
  4. 14
      components/checkbox/__tests__/group.test.tsx
  5. 16
      components/slider/__tests__/index.test.tsx
  6. 2
      tests/utils.tsx

47
components/affix/index.tsx

@ -1,7 +1,7 @@
import classNames from 'classnames';
import ResizeObserver from 'rc-resize-observer';
import omit from 'rc-util/lib/omit';
import * as React from 'react';
import React, { createRef, forwardRef, useContext } from 'react';
import type { ConfigConsumerProps } from '../config-provider';
import { ConfigContext } from '../config-provider';
import throttleByAnimationFrame from '../_util/throttleByAnimationFrame';
@ -50,7 +50,6 @@ export interface AffixState {
placeholderStyle?: React.CSSProperties;
status: AffixStatus;
lastAffix: boolean;
prevTarget: Window | HTMLElement | null;
}
@ -63,11 +62,11 @@ class Affix extends React.Component<InternalAffixProps, AffixState> {
prevTarget: null,
};
placeholderNode: HTMLDivElement;
private placeholderNodeRef = createRef<HTMLDivElement>();
fixedNode: HTMLDivElement;
private fixedNodeRef = createRef<HTMLDivElement>();
private timeout: NodeJS.Timeout | null;
private timer: NodeJS.Timeout | null;
context: ConfigConsumerProps;
@ -88,7 +87,7 @@ class Affix extends React.Component<InternalAffixProps, AffixState> {
if (targetFunc) {
// [Legacy] Wait for parent component ref has its value.
// We should use target as directly element instead of function which makes element check hard.
this.timeout = setTimeout(() => {
this.timer = setTimeout(() => {
addObserveTarget(targetFunc(), this);
// Mock Event object.
this.updatePosition();
@ -119,14 +118,13 @@ class Affix extends React.Component<InternalAffixProps, AffixState> {
) {
this.updatePosition();
}
this.measure();
}
componentWillUnmount() {
if (this.timeout) {
clearTimeout(this.timeout);
this.timeout = null;
if (this.timer) {
clearTimeout(this.timer);
this.timer = null;
}
removeObserveTarget(this);
this.updatePosition.cancel();
@ -141,20 +139,17 @@ class Affix extends React.Component<InternalAffixProps, AffixState> {
getOffsetBottom = () => this.props.offsetBottom;
savePlaceholderNode = (node: HTMLDivElement) => {
this.placeholderNode = node;
};
saveFixedNode = (node: HTMLDivElement) => {
this.fixedNode = node;
};
// =================== Measure ===================
measure = () => {
const { status, lastAffix } = this.state;
const { onChange } = this.props;
const targetFunc = this.getTargetFunc();
if (status !== AffixStatus.Prepare || !this.fixedNode || !this.placeholderNode || !targetFunc) {
if (
status !== AffixStatus.Prepare ||
!this.fixedNodeRef.current ||
!this.placeholderNodeRef.current ||
!targetFunc
) {
return;
}
@ -170,7 +165,7 @@ class Affix extends React.Component<InternalAffixProps, AffixState> {
status: AffixStatus.None,
};
const targetRect = getTargetRect(targetNode);
const placeholderReact = getTargetRect(this.placeholderNode);
const placeholderReact = getTargetRect(this.placeholderNodeRef.current);
const fixedTop = getFixedTop(placeholderReact, targetRect, offsetTop);
const fixedBottom = getFixedBottom(placeholderReact, targetRect, offsetBottom);
@ -244,9 +239,9 @@ class Affix extends React.Component<InternalAffixProps, AffixState> {
const offsetBottom = this.getOffsetBottom();
const targetNode = targetFunc();
if (targetNode && this.placeholderNode) {
if (targetNode && this.placeholderNodeRef.current) {
const targetRect = getTargetRect(targetNode);
const placeholderReact = getTargetRect(this.placeholderNode);
const placeholderReact = getTargetRect(this.placeholderNodeRef.current);
const fixedTop = getFixedTop(placeholderReact, targetRect, offsetTop);
const fixedBottom = getFixedBottom(placeholderReact, targetRect, offsetBottom);
@ -288,9 +283,9 @@ class Affix extends React.Component<InternalAffixProps, AffixState> {
return (
<ResizeObserver onResize={this.updatePosition}>
<div {...props} ref={this.savePlaceholderNode}>
<div {...props} ref={this.placeholderNodeRef}>
{affixStyle && <div style={placeholderStyle} aria-hidden="true" />}
<div className={className} ref={this.saveFixedNode} style={affixStyle}>
<div className={className} ref={this.fixedNodeRef} style={affixStyle}>
<ResizeObserver onResize={this.updatePosition}>{children}</ResizeObserver>
</div>
</div>
@ -301,9 +296,9 @@ class Affix extends React.Component<InternalAffixProps, AffixState> {
// just use in test
export type InternalAffixClass = Affix;
const AffixFC = React.forwardRef<Affix, AffixProps>((props, ref) => {
const AffixFC = forwardRef<Affix, AffixProps>((props, ref) => {
const { prefixCls: customizePrefixCls } = props;
const { getPrefixCls } = React.useContext(ConfigContext);
const { getPrefixCls } = useContext<ConfigConsumerProps>(ConfigContext);
const affixPrefixCls = getPrefixCls('affix', customizePrefixCls);
const [wrapSSR, hashId] = useStyle(affixPrefixCls);

13
components/button/__tests__/index.test.tsx

@ -276,20 +276,13 @@ describe('Button', () => {
});
it('skip check 2 words when ConfigProvider disable this', () => {
let buttonInstance: any;
const buttonInstance = React.createRef<HTMLElement>();
render(
<ConfigProvider autoInsertSpaceInButton={false}>
<Button
ref={(node) => {
buttonInstance = node;
}}
>
test
</Button>
<Button ref={buttonInstance}>test</Button>
</ConfigProvider>,
);
Object.defineProperty(buttonInstance, 'textContent', {
Object.defineProperty(buttonInstance.current, 'textContent', {
get() {
throw new Error('Should not called!!!');
},

3
components/calendar/index.ts

@ -1,6 +1,7 @@
import type { Dayjs } from 'dayjs';
import dayjsGenerateConfig from 'rc-picker/lib/generate/dayjs';
import generateCalendar, { type CalendarProps } from './generateCalendar';
import type { CalendarProps } from './generateCalendar';
import generateCalendar from './generateCalendar';
const Calendar = generateCalendar<Dayjs>(dayjsGenerateConfig);

14
components/checkbox/__tests__/group.test.tsx

@ -214,17 +214,9 @@ describe('CheckboxGroup', () => {
});
it('should get div ref', () => {
const refCalls: HTMLDivElement[] = [];
render(
<Checkbox.Group
options={['Apple', 'Pear', 'Orange']}
ref={(node) => {
refCalls.push(node!);
}}
/>,
);
const [mountCall] = refCalls;
expect(mountCall.nodeName).toBe('DIV');
const ref = React.createRef<HTMLDivElement>();
render(<Checkbox.Group options={['Apple', 'Pear', 'Orange']} ref={ref} />);
expect(ref.current?.nodeName).toBe('DIV');
});
it('should support number option', () => {

16
components/slider/__tests__/index.test.tsx

@ -134,21 +134,13 @@ describe('Slider', () => {
});
it('should keepAlign by calling forcePopupAlign', async () => {
let ref: any;
render(
<SliderTooltip
title="30"
open
ref={(node) => {
ref = node;
}}
/>,
);
ref.forcePopupAlign = jest.fn();
const ref = React.createRef<any>();
render(<SliderTooltip title="30" open ref={ref} />);
ref.current.forcePopupAlign = jest.fn();
act(() => {
jest.runAllTimers();
});
expect(ref.forcePopupAlign).toHaveBeenCalled();
expect(ref.current.forcePopupAlign).toHaveBeenCalled();
});
it('tipFormatter should not crash with undefined value', () => {

2
tests/utils.tsx

@ -35,7 +35,7 @@ const customRender = (ui: ReactElement, options?: Omit<RenderOptions, 'wrapper'>
export function renderHook<T>(func: () => T): { result: React.RefObject<T> } {
const result = React.createRef<T>();
const Demo = () => {
const Demo: React.FC = () => {
(result as any).current = func();
return null;

Loading…
Cancel
Save