経験は何よりも饒舌

10年後に真価を発揮するかもしれないブログ 

Reactのコードを読む(1)

この前jQueryのコードを読んでなんとなくコードリーディングがわかってきたので今回はReactのコードを読んでいこうと思う。
wafuwafu13.hatenadiary.com

直近の目標は、以下のコードでどのようにして画面にhello worldが表示されるかを解明することである。

<!DOCTYPE html>
<html>
<head>
    <script src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/babel-standalone/6.26.0/babel.js"></script>
</head>
<body>
<div id="root">
</div>
<script type="text/babel">
    ReactDOM.render(
        <h1>hello world</h1>,
        document.getElementById('root')
    );
</script>
</body>
</html>

コードは今回も行数がわかりやすいようにGitHubにあげた。
github.com


まずは、ReactDOMが何なのかから見ていこうと思う。

<!DOCTYPE html>
<html>
<head>
    <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
</head>
<body>
<div id="root">
</div>
<script>
    console.log(ReactDOM)
</script>
</body>
</html>

このコードの出力結果は、以下のようなエラーである。

Uncaught TypeError: Cannot read property '__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED' of undefined
    at react-dom.development.js:15
    at react-dom.development.js:12
    at react-dom.development.js:13

react-dom.development.jsの15行目を見てみると、以下のような記述がある。
https://github.com/wafuwafu13/react-17-react-dom-17/blob/master/react-dom.development.js#L15

var ReactSharedInternals = React.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED;

この__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIREDは、react.development.jsの3533行目でエクスポートされている。
https://github.com/wafuwafu13/react-17-react-dom-17/blob/master/react.development.js#L3533

exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = ReactSharedInternals$1;

よって、react.development.jsも読み込まないといけない。

<!DOCTYPE html>
<html>
<head>
    <script src="https://unpkg.com/react@17/umd/react.development.js"></script>
    <script src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script>
</head>
<body>
<div id="root">
</div>
<script>
    console.log(ReactDOM)
</script>
</body>
</html>

今回の出力結果は、以下のようになる。

▽{__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: {…}, createPortal: ƒ, findDOMNode: ƒ, flushSync: ƒ, hydrate: ƒ, …}
 ▷createPortal: ƒ createPortal$1(children, container)
 ▷findDOMNode: ƒ findDOMNode(componentOrElement)
 ▷flushSync: ƒ flushSync(fn, a)
 ▷hydrate: ƒ hydrate(element, container, callback)
 ▷render: ƒ render(element, container, callback)
 ▷unmountComponentAtNode: ƒ unmountComponentAtNode(container)
 ▷unstable_batchedUpdates: ƒ batchedUpdates$1(fn, a)
 ▷unstable_createPortal: ƒ unstable_createPortal(children, container)
 ▷unstable_renderSubtreeIntoContainer: ƒ renderSubtreeIntoContainer(parentComponent, element, containerNode, callback)
 ▷version: "17.0.1"
 ▷__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED: {Events: Array(7)}
 ▷__proto__: Object

これらは、react-dom.development.jsの26280~26290行目でエクスポートされている。
https://github.com/wafuwafu13/react-17-react-dom-17/blob/master/react-dom.development.js#L26280

exports.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = Internals;
...
exports.render = render;
...

次回から、このrender関数について見ていこうと思う。

wafuwafu13.hatenadiary.com