tiny-react是一个为了简化react源码学习的库,和react17的区别就是少了不少功能,只实现了核心的逻辑,和preact这种react-like库有着根本区别,preact更像是一个和react有着相同的接口可是实现细节却不尽相同的react,而tiny-react是从react官方仓库精简而来,它更像官方react的阉割版,因此每一行代码,每个函数都能在react最新的官方仓库中找到出处,并且总共的代码只有6千多行,刨除掉ReactDOM只有4000多行,能让React源码学习的难度大大下降react
/** * 打开performance查看Concurrent Mode下render阶段的时间切片 * 点击一下按钮而后会开始BitList的render阶段,能够看处处于render阶段(也就是点击按钮后的前几秒)时input * 是能够输入的,可是因为要渲染的东西太多,到commit阶段时就会开始卡住, * 因此此时会卡顿的瓶颈在浏览器渲染太耗时,而不是在react */ import React, { useState } from '../packages/react' const data = Array.from({ length: 50e4 }, (_, i) => i) const CHUNK_SIZE = 1e4 / 10 /** * fiber是最小的工做粒度,若是要保证render过程当中能保证浏览器能 * 处于交互的状态就得保证一个fiber render的过程不会太耗 * 事件,因此能够根据机能设置合适的CHUNK_SIZE * @param param0 * @returns */ const Chunk = ({ start }: { start: number }): any => { const end = Math.min(data.length, start + CHUNK_SIZE) const children = Array.from({ length: end - start }) for (let i = start; i < end; ++i) { children[i - start] = <div key={i}>{i}</div> } return children } const BigList = () => { const children = [] for (let i = 0; i < data.length; i += CHUNK_SIZE) { children.push(<Chunk start={i} />) } return <div>{children}</div> } export const TimeSlicingDemo = () => { const [isShowBigList, setIsShowBigList] = useState(false) return ( <div> <button onClick={() => { //因为点击事件内产生的更新会按Sync优先级处理 //咱们手动用setTimeout去掉点击事件的执行上下文 setTimeout(() => { setIsShowBigList(!isShowBigList) }) }} > toggle BigList </button> <br /> <input placeholder="输入点东西,看看交互有没有被阻塞" /> <br /> {isShowBigList ? <BigList /> : null} </div> ) }
import React, { useState, useEffect } from '../packages/react' export const PriorityScheduling = () => { const [count, updateCount] = useState(0) const onClick = () => { updateCount((count) => count + 2) } console.log({ count }) useEffect(() => { //暂时不支持ref直接用选择器获取 const button = document.getElementById('discretEventDispatcher')! setTimeout(() => updateCount(1), 1000) setTimeout(() => { button.click() //根据机能给第二个setTimeout一个合适的时间,或者适当的加长数组的长度 //以保证点击事件触发时,前一个低优先级的更新的render阶段尚未完成 //才能看到插队状况发生 }, 1030) }, []) return ( <div> <button id="discretEventDispatcher" onClick={onClick}> 增长2 </button> <div> {Array.from(new Array(10000)).map((v, index) => ( <span key={index}>{count}</span> ))} </div> </div> ) }