fix(Anchor): onChange method is not updated (#41934)

This commit is contained in:
JiaQi 2023-04-23 19:59:29 +08:00 committed by GitHub
parent 99f0db6ea6
commit a573dde6ed
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 51 additions and 3 deletions

View File

@ -212,7 +212,7 @@ const AnchorContent: React.FC<InternalAnchorProps> = (props) => {
return ''; return '';
}; };
const setCurrentActiveLink = (link: string) => { const setCurrentActiveLink = useEvent((link: string) => {
if (activeLinkRef.current === link) { if (activeLinkRef.current === link) {
return; return;
} }
@ -225,7 +225,7 @@ const AnchorContent: React.FC<InternalAnchorProps> = (props) => {
// onChange should respect the original link (which may caused by // onChange should respect the original link (which may caused by
// window scroll or user click), not the new link // window scroll or user click), not the new link
onChange?.(link); onChange?.(link);
}; });
const handleScroll = React.useCallback(() => { const handleScroll = React.useCallback(() => {
if (animating.current) { if (animating.current) {

View File

@ -1,9 +1,10 @@
import React, { useState } from 'react';
import { resetWarned } from 'rc-util/lib/warning'; import { resetWarned } from 'rc-util/lib/warning';
import React, { useState } from 'react';
import scrollIntoView from 'scroll-into-view-if-needed'; import scrollIntoView from 'scroll-into-view-if-needed';
import Anchor from '..'; import Anchor from '..';
import { act, fireEvent, render, waitFakeTimer } from '../../../tests/utils'; import { act, fireEvent, render, waitFakeTimer } from '../../../tests/utils';
import Button from '../../button';
import type { AnchorDirection } from '../Anchor'; import type { AnchorDirection } from '../Anchor';
const { Link } = Anchor; const { Link } = Anchor;
@ -373,6 +374,53 @@ describe('Anchor Render', () => {
expect(onChange).toHaveBeenLastCalledWith(`#${hash2}`); expect(onChange).toHaveBeenLastCalledWith(`#${hash2}`);
}); });
it('should be used the latest onChange method', () => {
const hash1 = getHashUrl();
const hash2 = getHashUrl();
const beforeFn = jest.fn();
const afterFn = jest.fn();
const Demo: React.FC = () => {
const [trigger, setTrigger] = useState(false);
const onChange = trigger ? afterFn : beforeFn;
return (
<>
<Button className="test-button" onClick={() => setTrigger(true)} />
<Anchor
onChange={onChange}
items={[
{
key: hash1,
href: `#${hash1}`,
title: hash1,
},
{
key: hash2,
href: `#${hash2}`,
title: hash2,
},
]}
/>
</>
);
};
const { container } = render(<Demo />);
expect(beforeFn).toHaveBeenCalled();
expect(afterFn).not.toHaveBeenCalled();
beforeFn.mockClear();
afterFn.mockClear();
fireEvent.click(container.querySelector('.test-button')!);
fireEvent.click(container.querySelector(`a[href="#${hash2}"]`)!);
expect(beforeFn).not.toHaveBeenCalled();
expect(afterFn).toHaveBeenCalled();
});
it('handles invalid hash correctly', () => { it('handles invalid hash correctly', () => {
const { container } = render( const { container } = render(
<Anchor items={[{ key: 'title', href: 'nonexistent', title: 'title' }]} />, <Anchor items={[{ key: 'title', href: 'nonexistent', title: 'title' }]} />,