Skip to content

Commit 725e09d

Browse files
committed
fix: noop-renderer support Fragment
1 parent 4fff899 commit 725e09d

File tree

8 files changed

+60
-21
lines changed

8 files changed

+60
-21
lines changed

demos/noop-renderer/index.html

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
4+
<head>
5+
<meta charset="UTF-8" />
6+
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
7+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
8+
<title>noop-renderer测试</title>
9+
</head>
10+
11+
<body>
12+
<div id="root"></div>
13+
<script type="module" src="main.tsx"></script>
14+
</body>
15+
16+
</html>

demos/noop-renderer/main.tsx

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { useState, useEffect } from 'react';
2+
import * as ReactNoop from 'react-noop-renderer';
3+
4+
const root = ReactNoop.createRoot();
5+
6+
function Parent() {
7+
return (
8+
<>
9+
<Child />
10+
<div>hello world</div>
11+
</>
12+
);
13+
}
14+
15+
function Child() {
16+
return 'Child';
17+
}
18+
19+
root.render(<Parent />);
20+
21+
window.root = root;

demos/noop-renderer/vite-env.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
/// <reference types="vite/client" />

demos/vite.config.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,16 @@ export default defineConfig({
2626
find: 'react-reconciler',
2727
replacement: path.resolve(__dirname, '../packages/react-reconciler')
2828
},
29+
{
30+
find: 'react-noop-renderer',
31+
replacement: path.resolve(__dirname, '../packages/react-noop-renderer')
32+
},
2933
{
3034
find: 'hostConfig',
3135
replacement: path.resolve(
3236
__dirname,
33-
'../packages/react-dom/src/hostConfig.ts'
37+
'../packages/react-noop-renderer/src/hostConfig.ts'
38+
// '../packages/react-dom/src/hostConfig.ts'
3439
)
3540
}
3641
]

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
"license": "MIT",
77
"scripts": {
88
"build:dev": "rm -rf dist && rollup --config scripts/rollup/dev.config.js",
9-
"demo": "vite serve demos/fragment --config demos/vite.config.js --force",
9+
"demo": "vite serve demos/noop-renderer --config demos/vite.config.js --force",
1010
"lint": "eslint --ext .ts,.jsx,.tsx --fix --quiet ./packages",
1111
"test": "jest --config scripts/jest/jest.config.js"
1212
},

packages/react-dom/src/SyntheticEvent.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export interface DOMElement extends Element {
2929
function createSyntheticEvent(e: Event): SyntheticEvent {
3030
const syntheticEvent = e as SyntheticEvent;
3131
syntheticEvent.__stopPropagation = false;
32-
const originStopPropagation = e.stopPropagation;
32+
const originStopPropagation = e.stopPropagation.bind(e);
3333

3434
syntheticEvent.stopPropagation = () => {
3535
syntheticEvent.__stopPropagation = true;

packages/react-noop-renderer/src/ReactNoop.ts

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { ReactElement } from 'shared/ReactTypes';
2-
import { REACT_ELEMENT_TYPE } from 'shared/ReactSymbols';
2+
import { REACT_ELEMENT_TYPE, REACT_FRAGMENT_TYPE } from 'shared/ReactSymbols';
33
import Reconciler from 'react-reconciler';
44
import * as Scheduler from 'scheduler';
55
import { Container, Instance } from './hostConfig';
@@ -9,35 +9,34 @@ let idCounter = 0;
99
export function createRoot() {
1010
const container: Container = {
1111
rootID: idCounter++,
12-
pendingChildren: [],
1312
children: []
1413
};
1514
const root = Reconciler.createContainer(container);
1615

17-
function getChildren(root: Container) {
18-
if (root) {
19-
return root.children;
16+
function getChildren(parent: Container | Instance) {
17+
if (parent) {
18+
return parent.children;
2019
}
2120
return null;
2221
}
2322

2423
function getChildrenAsJSX(root: Container) {
2524
const children = childToJSX(getChildren(root));
26-
if (children === null) {
27-
return null;
28-
}
2925
if (Array.isArray(children)) {
30-
// 对应混合了Instance与TextInstance,应该用Fragment处理
31-
console.error('TODO Fragment的case,还未实现');
26+
return {
27+
$$typeof: REACT_ELEMENT_TYPE,
28+
type: REACT_FRAGMENT_TYPE,
29+
key: null,
30+
ref: null,
31+
props: { children },
32+
__mark: 'KaSong'
33+
};
3234
}
3335
return children;
3436
}
3537

3638
// 递归将整棵子树变为JSX
3739
function childToJSX(child: any): any {
38-
if (child === null) {
39-
return null;
40-
}
4140
if (['string', 'number'].includes(typeof child)) {
4241
return child;
4342
}
@@ -58,7 +57,6 @@ export function createRoot() {
5857
}
5958
// 这是Instance
6059
if (Array.isArray(child.children)) {
61-
// This is an instance.
6260
const instance: Instance = child;
6361
const children = childToJSX(instance.children);
6462
const props = instance.props;
@@ -71,7 +69,7 @@ export function createRoot() {
7169
type: instance.type,
7270
key: null,
7371
ref: null,
74-
props: props,
72+
props,
7573
__mark: 'KaSong'
7674
};
7775
}

packages/react-noop-renderer/src/hostConfig.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
export interface Container {
22
rootID: number;
3-
pendingChildren: (Instance | TextInstance)[];
43
children: (Instance | TextInstance)[];
54
}
65
export interface Instance {
@@ -17,15 +16,14 @@ export interface TextInstance {
1716
}
1817

1918
import { FiberNode } from 'react-reconciler/src/fiber';
20-
import { DefaultLane } from 'react-reconciler/src/fiberLanes';
2119
import { HostText } from 'react-reconciler/src/workTags';
2220

2321
let instanceCounter = 0;
2422

2523
export const createInstance = (type: string, props: any): Instance => {
2624
const instance = {
2725
id: instanceCounter++,
28-
type: type,
26+
type,
2927
children: [],
3028
parent: -1,
3129
props

0 commit comments

Comments
 (0)