How to use reconcileSingleElement method in Playwright Internal

Best JavaScript code snippet using playwright-internal

Run Playwright Internal automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

ReactChildFiber.js

Source: ReactChildFiber.js Github

copy
1import { REACT_ELEMENT_TYPE } from "./ReactSymbols";
2import { createFiberFromElement } from './ReactFiber';
3import { Placement } from './ReactFiberFlags';
4
5function childReconciler(shouldTrackSideEffects) {
6    function reconcileSingleElement(returnFiber, currentFirstChild, element) {
7        const created = createFiberFromElement(element);//div#title
8        created.return = returnFiber;
9        return created;
10    }
11    function placeSingleChild(newFiber) {
12        //如果当前需要跟踪父作用,并且当前这个新的fiber它的替身不存在
13        if (shouldTrackSideEffects && !newFiber.alternate) {
14            //给这个新fiber添加一个副作用,表示在未来提前阶段的DOM操作中会向真实DOM树中添加此节点
15            newFiber.flags = Placement;
16        }
17        return newFiber;
18    }
19    /**
20     * 
21     * @param {*} returnFiber 新的父fiber
22     * @param {*} currentFirstChild current就是老的意思,老的第一个子fiber
23     * @param {*} newChild 新的虚拟DOM
24     */
25    function reconcileChildFibers(returnFiber, currentFirstChild, newChild) {
26        //判断newChild是不是一个对象,如果是的话说明新的虚拟DOM只有一个React元素节点
27        const isObject = typeof newChild === 'object' && (newChild);
28        //说明新的虚拟DOM是单节点
29        if (isObject) {
30            switch (newChild.$$typeof) {
31                case REACT_ELEMENT_TYPE:
32                    return placeSingleChild(reconcileSingleElement(
33                        returnFiber, currentFirstChild, newChild
34                    ));
35            }
36        }
37    }
38    return reconcileChildFibers;
39}
40
41export const reconcileChildFibers = childReconciler(true);
42export const mountChildFibers = childReconciler(false);
Full Screen

diff.js

Source: diff.js Github

copy
1// react的diff预设了三个限制
2// 1.只对同级元素进行Diff。如果一个DOM节点在前后两次更新中跨越了层级,那么React不会尝试复用他。
3
4// 2.两个不同类型的元素会产生出不同的树。如果元素由div变为p,React会销毁div及其子孙节点,并新建p及其子孙节点。
5
6// 3.开发者可以通过 key prop来暗示哪些子元素在不同的渲染下能保持稳定
7
8// 根据newChild类型选择不同diff函数处理
9function reconcileChildFibers(
10    returnFiber: Fiber,
11    currentFirstChild: Fiber | null,
12    newChild: any,
13): Fiber | null {
14
15    const isObject = typeof newChild === 'object' && newChild !== null;
16
17    if (isObject) {
18        // object类型,可能是 REACT_ELEMENT_TYPE 或 REACT_PORTAL_TYPE
19        switch (newChild.$$typeof) {
20            case REACT_ELEMENT_TYPE:
21            // 调用 reconcileSingleElement 处理
22            // // ...省略其他case
23        }
24    }
25
26    if (typeof newChild === 'string' || typeof newChild === 'number') {
27        // 调用 reconcileSingleTextNode 处理
28        // ...省略
29    }
30
31    if (isArray(newChild)) {
32        // 调用 reconcileChildrenArray 处理
33        // ...省略
34    }
35
36    // 一些其他情况调用处理函数
37    // ...省略
38
39    // 以上都没有命中,删除节点
40    return deleteRemainingChildren(returnFiber, currentFirstChild);
41}
42
43// 我们可以从同级的节点数量将Diff分为两类:
44
45// 1.当newChild类型为object、number、string,代表同级只有一个节点
46
47// 2.当newChild类型为Array,同级有多个节点
48
49
50//判断DOM节点是否可以复用
51function reconcileSingleElement(
52    returnFiber: Fiber,
53    currentFirstChild: Fiber | null,
54    element: ReactElement
55): Fiber {
56    const key = element.key;
57    let child = currentFirstChild;
58
59    // 首先判断是否存在对应DOM节点
60    while (child !== null) {
61        // 上一次更新存在DOM节点,接下来判断是否可复用
62
63        // 首先比较key是否相同
64        if (child.key === key) {
65
66            // key相同,接下来比较type是否相同
67
68            switch (child.tag) {
69                // ...省略case
70
71                default: {
72                    if (child.elementType === element.type) {
73                        // type相同则表示可以复用
74                        // 返回复用的fiber
75                        return existing;
76                    }
77
78                    // type不同则跳出循环
79                    break;
80                }
81            }
82            // 代码执行到这里代表:key相同但是type不同
83            // 将该fiber及其兄弟fiber标记为删除
84            deleteRemainingChildren(returnFiber, child);
85            break;
86        } else {
87            // key不同,将该fiber标记为删除
88            deleteChild(returnFiber, child);
89        }
90        child = child.sibling;
91    }
92
93    // 创建新Fiber,并返回 ...省略
94}
95
96//diff会进行两轮遍历
97//第一轮:判断新旧fiber是否可以复用,不可以复用进入第二轮
98//第二轮:1.newChildren与oldFiber同时遍历完
99//       那就是最理想的情况:只需在第一轮遍历进行组件更新。此时Diff结束。
100
101//       2.newChildren没遍历完,oldFiber遍历完
102//       已有的DOM节点都复用了,这时还有新加入的节点,意味着本次更新有新节点插入,我们只需要遍历剩下的newChildren为生成的workInProgress fiber依次标记Placement。
103
104//       3.newChildren遍历完,oldFiber没遍历完
105//       意味着本次更新比之前的节点数量少,有节点被删除了。所以需要遍历剩下的oldFiber,依次标记Deletion。
106
107//       4.newChildren与oldFiber都没遍历完
108//       这意味着有节点在这次更新中改变了位置。
109
110
Full Screen

Accelerate Your Automation Test Cycles With LambdaTest

Leverage LambdaTest’s cloud-based platform to execute your automation tests in parallel and trim down your test execution time significantly. Your first 100 automation testing minutes are on us.

Try LambdaTest

Run JavaScript Tests on LambdaTest Cloud Grid

Execute automation tests with Playwright Internal on a cloud-based Grid of 3000+ real browsers and operating systems for both web and mobile applications.

Test now for Free
LambdaTestX

We use cookies to give you the best experience. Cookies help to provide a more personalized experience and relevant advertising for you, and web analytics for us. Learn More in our Cookies policy, Privacy & Terms of service

Allow Cookie
Sarah

I hope you find the best code examples for your project.

If you want to accelerate automated browser testing, try LambdaTest. Your first 100 automation testing minutes are FREE.

Sarah Elson (Product & Growth Lead)