Skip to content

Commit e391aae

Browse files
authored
React 19 (#865)
feat: Add support for React 19 BREAKING CHANGE: To simplify the library maintenance, this major version only support React 19.
1 parent d9e795f commit e391aae

File tree

5 files changed

+104
-177
lines changed

5 files changed

+104
-177
lines changed

.github/workflows/continuous-integration.yaml

Lines changed: 6 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -5,34 +5,17 @@ jobs:
55
name: Continuous Integration
66
runs-on: ubuntu-latest
77
steps:
8-
- uses: actions/checkout@v2
9-
- uses: actions/setup-node@v2-beta
8+
- uses: actions/checkout@v4
9+
- uses: actions/setup-node@v4
1010
with:
11-
node-version: '14'
12-
- name: Get yarn cache directory path
13-
id: yarn-cache-dir-path
14-
run: echo "::set-output name=dir::$(yarn cache dir)"
15-
- uses: actions/cache@v2
16-
id: yarn-cache
17-
with:
18-
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
19-
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
20-
restore-keys: |
21-
${{ runner.os }}-yarn-
11+
node-version: '20'
12+
cache: 'yarn'
2213
- run: yarn install --frozen-lockfile
2314
- run: yarn run test
2415
- run: yarn run lint
2516
- run: yarn run flow
26-
- run: yarn run smoke cjs 15.6.2
27-
- run: yarn run smoke esm 15.6.2
28-
- run: yarn run smoke cjs 16.7.0
29-
- run: yarn run smoke esm 16.7.0
30-
- run: yarn run smoke cjs 17.0.2
31-
- run: yarn run smoke esm 17.0.2
32-
- run: yarn run smoke cjs 18.0.0
33-
- run: yarn run smoke esm 18.0.0
34-
- run: yarn run smoke cjs 18.1.0
35-
- run: yarn run smoke esm 18.1.0
17+
- run: yarn run smoke cjs 19.0.0
18+
- run: yarn run smoke esm 19.0.0
3619
- run: yarn run smoke cjs latest
3720
- run: yarn run smoke esm latest
3821
- run: yarn run smoke cjs next

package.json

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
{
22
"name": "react-element-to-jsx-string",
3-
"version": "15.0.0",
3+
"version": "16.0.0",
44
"description": "Turn a ReactElement into the corresponding JSX string.",
5+
"packageManager": "[email protected]+sha1.ac34549e6aa8e7ead463a7407e1c7390f61a6610",
56
"main": "dist/cjs/index.js",
67
"module": "dist/esm/index.js",
78
"browser": "dist/cjs/index.js",
@@ -43,8 +44,9 @@
4344
"@babel/preset-react": "7.24.1",
4445
"@commitlint/cli": "8.3.6",
4546
"@commitlint/config-angular": "8.3.6",
47+
"@testing-library/dom": "10.4.0",
4648
"@testing-library/jest-dom": "5.17.0",
47-
"@testing-library/react": "13.4.0",
49+
"@testing-library/react": "16.1.0",
4850
"babel-eslint": "10.1.0",
4951
"babel-jest": "24.9.0",
5052
"babel-register": "6.26.0",
@@ -67,9 +69,9 @@
6769
"lint-staged": "10.5.4",
6870
"mversion": "2.0.1",
6971
"prettier": "1.19.1",
70-
"react": "18.2.0",
71-
"react-dom": "18.2.0",
72-
"react-test-renderer": "18.2.0",
72+
"react": "19.0.0",
73+
"react-dom": "19.0.0",
74+
"react-is": "19.0.0",
7375
"rollup": "2.79.1",
7476
"rollup-plugin-babel": "4.4.0",
7577
"rollup-plugin-node-builtins": "2.1.2",
@@ -78,13 +80,13 @@
7880
"rollup-plugin-sourcemaps": "0.6.3"
7981
},
8082
"peerDependencies": {
81-
"react": "^0.14.8 || ^15.0.1 || ^16.0.0 || ^17.0.1 || ^18.0.0",
82-
"react-dom": "^0.14.8 || ^15.0.1 || ^16.0.0 || ^17.0.1 || ^18.0.0"
83+
"react": "^19.0.0",
84+
"react-dom": "^19.0.0",
85+
"react-is": "^19.0.0"
8386
},
8487
"dependencies": {
8588
"@base2/pretty-print-object": "1.0.2",
86-
"is-plain-object": "5.0.0",
87-
"react-is": "18.2.0"
89+
"is-plain-object": "5.0.0"
8890
},
8991
"jest": {
9092
"setupFilesAfterEnv": [

src/index.spec.js

Lines changed: 16 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@
55
/* @flow */
66

77
/* eslint-disable react/no-string-refs */
8+
/* eslint-disable react/prop-types */
89

910
import React, { Fragment, Component } from 'react';
10-
import { createRenderer } from 'react-test-renderer/shallow';
1111
import { render, screen } from '@testing-library/react';
1212
import reactElementToJSXString, { preserveFunctionLineBreak } from './index';
1313
import AnonymousStatelessComponent from './AnonymousStatelessComponent';
@@ -640,47 +640,6 @@ describe('reactElementToJSXString(ReactElement)', () => {
640640
);
641641
});
642642

643-
it('reactElementToJSXString(decorator(<span />)', () => {
644-
function myDecorator(ComposedComponent) {
645-
class MyDecorator extends React.Component {
646-
render() {
647-
return (
648-
<div>{React.createElement(ComposedComponent.type, this.props)}</div>
649-
);
650-
}
651-
}
652-
MyDecorator.displayName = `${ComposedComponent.name}-Decorated`;
653-
return MyDecorator;
654-
}
655-
656-
const NestedSpan = myDecorator(<span />);
657-
const renderer = createRenderer();
658-
renderer.render(<NestedSpan />);
659-
expect(reactElementToJSXString(renderer.getRenderOutput())).toEqual(
660-
`<div>
661-
<span />
662-
</div>`
663-
);
664-
});
665-
666-
it('reactElementToJSXString(<div>Hello {this.props.name}</div>', () => {
667-
/* eslint-disable react/prop-types */
668-
class InlineProps extends React.Component {
669-
render() {
670-
return <div>Hello {this.props.name}</div>;
671-
}
672-
}
673-
674-
const renderer = createRenderer();
675-
renderer.render(<InlineProps name="John" />);
676-
const actualElement = renderer.getRenderOutput();
677-
expect(reactElementToJSXString(actualElement)).toEqual(
678-
`<div>
679-
Hello John
680-
</div>`
681-
);
682-
});
683-
684643
it('reactElementToJSXString(<div type={Symbol("test")}/>)', () => {
685644
expect(reactElementToJSXString(<div type={Symbol('test')} />)).toEqual(
686645
"<div type={Symbol('test')} />"
@@ -1300,6 +1259,21 @@ describe('reactElementToJSXString(ReactElement)', () => {
13001259
</Context.Provider>`);
13011260
});
13021261

1262+
it('should stringify `Context` correctly', () => {
1263+
const Ctx = React.createContext();
1264+
const App = () => {};
1265+
1266+
expect(
1267+
reactElementToJSXString(
1268+
<Ctx value={null}>
1269+
<App />
1270+
</Ctx>
1271+
)
1272+
).toEqual(`<Context.Provider value={null}>
1273+
<App />
1274+
</Context.Provider>`);
1275+
});
1276+
13031277
it('should stringify `Contex.Provider` with `displayName` correctly', () => {
13041278
const Ctx = React.createContext();
13051279
Ctx.displayName = 'MyCtx';

src/parser/parseReactElement.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ const getReactElementDisplayName = (element: ReactElement<*>): string => {
6161
case isContextConsumer(element):
6262
return `${element.type._context.displayName || 'Context'}.Consumer`;
6363
case isContextProvider(element):
64-
return `${element.type._context.displayName || 'Context'}.Provider`;
64+
return `${element.type.displayName || 'Context'}.Provider`;
6565
case isLazy(element):
6666
return 'Lazy';
6767
case isProfiler(element):
@@ -112,9 +112,6 @@ const parseReactElement = (
112112
const displayName = displayNameFn(element);
113113

114114
const props = filterProps(element.props, noChildren);
115-
if (element.ref !== null) {
116-
props.ref = element.ref;
117-
}
118115

119116
const key = element.key;
120117
if (typeof key === 'string' && key.search(/^\./)) {

0 commit comments

Comments
 (0)