亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

React實(shí)時(shí)預(yù)覽react-live源碼解析

 更新時(shí)間:2022年08月15日 11:51:42   作者:嘿嘿Z  
這篇文章主要為大家介紹了React實(shí)時(shí)預(yù)覽react-live源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

引言

react-live 是一個(gè) react 的實(shí)時(shí)編輯器,可直接編輯 react 代碼,并實(shí)時(shí)預(yù)覽。可以看下官方的預(yù)覽圖:

本文針對的源碼版本

src
├── components
│   ├── Editor
│   │   └── index.js
│   └── Live
│       ├── LiveContext.js
│       ├── LiveEditor.js
│       ├── LiveError.js
│       ├── LivePreview.js
│       ├── LiveProvider.js
│       └── LiveProvider.test.js
├── constants
│   └── theme.js
├── hoc
│   └── withLive.js
├── index.js
└── utils
    ├── test
    │   ├── errorBoundary.test.js
    │   ├── renderer.js
    │   └── transpile.test.js
    └── transpile
        ├── errorBoundary.js
        ├── evalCode.js
        ├── index.js
        └── transform.js

源碼解讀

輸入內(nèi)容

先看下導(dǎo)出內(nèi)容,包括:

  • Editor:編輯器
  • LiveProvider:實(shí)時(shí)編輯環(huán)境的 Provider,Context.Provider
  • LiveEditor:實(shí)時(shí)編輯上下文的編輯器
  • LiveError:實(shí)時(shí)編輯上下文的報(bào)錯(cuò)
  • LivePreview:實(shí)時(shí)編輯上下文的預(yù)覽
  • LiveContext:實(shí)時(shí)編輯的 Context
  • withLive:實(shí)時(shí)編輯上下文的 HOC

文件結(jié)構(gòu)和組件拆分一目了然。

Provider

先看下 Provider,它提供了以下內(nèi)容:

  • element:實(shí)時(shí)編輯輸出的元素
  • error:當(dāng)前的報(bào)錯(cuò)信息
  • code:當(dāng)前編輯的代碼
  • language:代碼語言
  • theme:代碼編輯器主題
  • disabled:是否禁用
  • onError:報(bào)錯(cuò)的回調(diào)
  • onChange:代碼編輯時(shí)的回調(diào)

Provider 用來收集代碼變更,然后通過 transpileAsync 將代碼編譯生成組件實(shí)例:

function transpileAsync(newCode) {
    const errorCallback = error => {
        setState({ error: error.toString(), element: undefined });
    };
    try {
        const transformResult = transformCode ? transformCode(newCode) : newCode;
        return Promise.resolve(transformResult)
            .then(transformedCode => {
                const renderElement = element => setState({ error: undefined, element });
                // Transpilation arguments
                const input = {
                    code: transformedCode,
                    scope
                };
                if (noInline) {
                    setState({ error: undefined, element: null }); // Reset output for async (no inline) evaluation
                    renderElementAsync(input, renderElement, errorCallback);
                } else {
                    renderElement(generateElement(input, errorCallback));
                }
            })
            .catch(errorCallback);
    } catch (e) {
        errorCallback(e);
        return Promise.resolve();
    }
}

renderElementAsync 可以先無視,主要是用于 noInline 模式下調(diào)用 render 進(jìn)行渲染,邏輯與非 noInline 模式下類似。

generateElement

實(shí)時(shí)預(yù)覽的核心部分就在這里了,它會將代碼先進(jìn)行編譯,然后執(zhí)行代碼,取得返回值。

const generateElement = ({ code = '', scope = {} }, errorCallback) => {
    // NOTE: Remove trailing semicolon to get an actual expression.
    const codeTrimmed = code.trim().replace(/;$/, '');
    // NOTE: Workaround for classes and arrow functions.
    const transformed = transform(`return (${codeTrimmed})`).trim();
    return errorBoundary(evalCode(transformed, { React, ...scope }), errorCallback);
};

代碼如上,它會先去掉頭尾空白,然后去掉結(jié)尾的分號,這一步是為了下一步的 return 拼接能夠正常返回。通過 return 拼接讓 react-live 能夠支持下述語法直接渲染:

直接寫一個(gè)匿名函數(shù):

() => <h3>So functional. Much wow!</h3>;

直接寫 jsx

<h3>Hello World!</h3>

class 組件:

class Comp extends React.Component {
    render() {
        return <center>component</center>;
    }
}

不過也導(dǎo)致了一定的學(xué)習(xí)成本,如果寫多個(gè)函數(shù),多個(gè)組件,嵌套等情況下會讓人覺得語法很奇怪。

transform 就是將代碼通過 sucrase 進(jìn)行轉(zhuǎn)譯,處理 jsx、class 這些語法,可以理解為通過 babel 轉(zhuǎn)譯。

早期的 react-live 通過 buble 進(jìn)行轉(zhuǎn)譯,能夠支持 jsx 注釋,現(xiàn)在由于 sucrase 不支持 jsx 注釋,所以新版無法使用 jsx 注釋來控制 jsx 渲染引擎。

/** @jsx mdx */
// 新版上述注釋會失效

隨后將轉(zhuǎn)譯的代碼通過 evalCode 轉(zhuǎn)換為 React element,此處會將 scopeReact 傳入 evalCode 中。

const evalCode = (code, scope) => {
    const scopeKeys = Object.keys(scope);
    const scopeValues = scopeKeys.map(key => scope[key]);
    return new Function(...scopeKeys, code)(...scopeValues);
};

evalCode 中使用 new Function 來構(gòu)造函數(shù),scope 就是在這里作為參數(shù)進(jìn)行注入。如果對 new Function 不理解的可以看我之前一篇關(guān)于 JS 沙箱的文章。

errorBoundary 則是一個(gè)簡單的 HOC,用來捕獲生成的組件運(yùn)行時(shí)的錯(cuò)誤信息,通過 errorCallback 拋出。

const errorBoundary = (Element, errorCallback) => {
    return class ErrorBoundary extends Component {
        componentDidCatch(error) {
            errorCallback(error);
        }
        render() {
            return typeof Element === 'function' ? <Element /> : React.isValidElement(Element) ? Element : null;
        }
    };
};

上面就是 react-live 能夠?qū)崟r(shí)預(yù)覽的核心代碼了。下面再看下其它幾個(gè)組件,都比較簡單。

其他組件

LivePreview 會接受 Provider 中的 Element,將其渲染。

LiveError 接受 Provider 中的 error 進(jìn)行渲染。

LiveEditor 則是接收 Providercode、language、theme、disabledonChange,提供編輯功能。

它的編輯器則是通過 useEditable 編輯,Prism 進(jìn)行代碼高亮。

總結(jié)

上述便是 react-live 的核心代碼,內(nèi)容并不多,通過 sucrase 實(shí)時(shí)編譯代碼,然后通過 new Function 構(gòu)造函數(shù)注入 scope 來生成 element 實(shí)現(xiàn)實(shí)時(shí)預(yù)覽,設(shè)計(jì)上通過拆離 EditorError、Preview 三部分,可以讓使用者自由組合組件的位置、樣式。

以上就是React實(shí)時(shí)預(yù)覽react-live源碼解析的詳細(xì)內(nèi)容,更多關(guān)于react live實(shí)時(shí)預(yù)覽的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 一文學(xué)會使用Remix寫API接口

    一文學(xué)會使用Remix寫API接口

    這篇文章主要為大家介紹了一文學(xué)會Remix寫API接口實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-04-04
  • React組件通信的實(shí)現(xiàn)示例

    React組件通信的實(shí)現(xiàn)示例

    在React中,組件通信是一個(gè)重要的概念,它允許不同組件之間進(jìn)行數(shù)據(jù)傳遞和交互,本文主要介紹了React組件通信的實(shí)現(xiàn)示例,感興趣的可以了解一下
    2023-11-11
  • 詳解React?的數(shù)據(jù)流和生命周期

    詳解React?的數(shù)據(jù)流和生命周期

    這篇文章主要介紹了React?的數(shù)據(jù)流和生命周期,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2022-08-08
  • 如何深入理解React的ref 屬性

    如何深入理解React的ref 屬性

    關(guān)于 Refs ,React 官網(wǎng)講解的對于新手來說不太友好,還是自己一字一句解讀后并以代碼驗(yàn)證的方式后真正理解的.
    2021-05-05
  • ReactNative踩坑之配置調(diào)試端口的解決方法

    ReactNative踩坑之配置調(diào)試端口的解決方法

    本篇文章主要介紹了ReactNative踩坑之配置調(diào)試端口的解決方法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2017-07-07
  • React實(shí)現(xiàn)倒計(jì)時(shí)功能組件

    React實(shí)現(xiàn)倒計(jì)時(shí)功能組件

    這篇文章主要為大家詳細(xì)介紹了如何通過React實(shí)現(xiàn)一個(gè)倒計(jì)時(shí)功能組件,文中的示例代碼講解詳細(xì),具有一定的學(xué)習(xí)價(jià)值,感興趣的小伙伴可以了解下
    2023-09-09
  • React學(xué)習(xí)之事件綁定的幾種方法對比

    React學(xué)習(xí)之事件綁定的幾種方法對比

    這篇文章主要給大家介紹了關(guān)于React學(xué)習(xí)之事件綁定的幾種方法對比,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-09-09
  • 再次談?wù)揜eact.js實(shí)現(xiàn)原生js拖拽效果引起的一系列問題

    再次談?wù)揜eact.js實(shí)現(xiàn)原生js拖拽效果引起的一系列問題

    React 起源于 Facebook 的內(nèi)部項(xiàng)目,因?yàn)樵摴緦κ袌錾纤?JavaScript MVC 框架,都不滿意,就決定自己寫一套,用來架設(shè) Instagram 的網(wǎng)站.本文給大家介紹React.js實(shí)現(xiàn)原生js拖拽效果,需要的朋友一起學(xué)習(xí)吧
    2016-04-04
  • react-native-fs實(shí)現(xiàn)文件下載、文本存儲的示例代碼

    react-native-fs實(shí)現(xiàn)文件下載、文本存儲的示例代碼

    本篇文章主要介紹了react-native-fs實(shí)現(xiàn)文件下載、文本存儲的示例代碼,具有一定的參考價(jià)值,有興趣的可以了解下
    2017-09-09
  • React獲取Java后臺文件流并下載Excel文件流程解析

    React獲取Java后臺文件流并下載Excel文件流程解析

    這篇文章主要介紹了React獲取Java后臺文件流下載Excel文件,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06

最新評論