この前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:13react-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関数について見ていこうと思う。