Skip to content

Commit a78b20c

Browse files
authored
fix: isFragment not support React 19 (#604)
1 parent 161915b commit a78b20c

File tree

4 files changed

+79
-2
lines changed

4 files changed

+79
-2
lines changed

src/Children/toArray.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1+
import isFragment from '../React/isFragment';
12
import React from 'react';
2-
import { isFragment } from 'react-is';
33

44
export interface Option {
55
keepEmpty?: boolean;

src/React/isFragment.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
const REACT_ELEMENT_TYPE_18 = Symbol.for('react.element');
2+
const REACT_ELEMENT_TYPE_19 = Symbol.for('react.transitional.element');
3+
const REACT_FRAGMENT_TYPE = Symbol.for('react.fragment');
4+
5+
/**
6+
* Compatible with React 18 or 19 to check if node is a Fragment.
7+
*/
8+
export default function isFragment(object: any) {
9+
return (
10+
// Base object type
11+
object &&
12+
typeof object === 'object' &&
13+
// React Element type
14+
(object.$$typeof === REACT_ELEMENT_TYPE_18 ||
15+
object.$$typeof === REACT_ELEMENT_TYPE_19) &&
16+
// React Fragment type
17+
object.type === REACT_FRAGMENT_TYPE
18+
);
19+
}

src/ref.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import type * as React from 'react';
22
import { isValidElement } from 'react';
3-
import { ForwardRef, isFragment, isMemo } from 'react-is';
3+
import { ForwardRef, isMemo } from 'react-is';
44
import useMemo from './hooks/useMemo';
5+
import isFragment from './React/isFragment';
56

67
export const fillRef = <T>(ref: React.Ref<T>, node: T) => {
78
if (typeof ref === 'function') {

tests/toArray-19.test.tsx

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
import React from 'react';
2+
import { render } from '@testing-library/react';
3+
import toArray from '../src/Children/toArray';
4+
5+
jest.mock('react', () => {
6+
const react19 = jest.requireActual('react-19');
7+
return react19;
8+
});
9+
10+
jest.mock('react-dom', () => {
11+
const reactDom19 = jest.requireActual('react-dom-19');
12+
return reactDom19;
13+
});
14+
15+
jest.mock('react-dom/client', () => {
16+
const reactDom19Client = jest.requireActual('react-dom-19/client');
17+
return reactDom19Client;
18+
});
19+
20+
jest.mock('react-dom/test-utils', () => {
21+
const reactDom19Test = jest.requireActual('react-dom-19/test-utils');
22+
return reactDom19Test;
23+
});
24+
25+
class UL extends React.Component<{
26+
children?: React.ReactNode;
27+
}> {
28+
render() {
29+
return <ul>{this.props.children}</ul>;
30+
}
31+
}
32+
33+
describe('toArray', () => {
34+
it('Fragment', () => {
35+
const ulRef = React.createRef<UL>();
36+
37+
render(
38+
<UL ref={ulRef}>
39+
<li key="1">1</li>
40+
<>
41+
<li key="2">2</li>
42+
<li key="3">3</li>
43+
</>
44+
<React.Fragment>
45+
<>
46+
<li key="4">4</li>
47+
<li key="5">5</li>
48+
</>
49+
</React.Fragment>
50+
</UL>,
51+
);
52+
53+
const children = toArray(ulRef.current.props.children);
54+
expect(children).toHaveLength(5);
55+
expect(children.map(c => c.key)).toEqual(['1', '2', '3', '4', '5']);
56+
});
57+
});

0 commit comments

Comments
 (0)