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> ) }