どうもです!今回はReactって始めてみたいけど正直始めるまでの環境構築大変だし、Create React App便利だけどコマンドはちょっと…。
はい!!それではCDNリンクを利用して既存のHTMLファイルにReact導入しちゃいましょう!。
公式ドキュメントさんでは『1分で追加』ってドヤ顔です。
でもそれぐらい簡単という事です。
やたらとNode.jsでコマンドを叩いたり、よく分かんないツールとかWebpack/Babelをやる必要がなくなるんです。
せっかくなのでReactやってる感を味わってもらいたいのでClass ComponentとSPA構築のReact-Routerを導入しましょう!。
HTMLファイルを用意
いつものことながら、テンプレファイル用意お願いします
テンプレHTMLの作成が出来ましたら、body内に
<div id="root"></div>
このように記述お願いします。
こうする事でこの中にあるもの全てが React DOM によって管理されるようになります。
次はReactのCDNのScriptタグをコピーしheadタグ内もしくはbody内の下部どちらかに貼り付けします。
<script src="https://unpkg.com/react@17/umd/react.production.min.js" crossorigin></script> <script src="https://unpkg.com/react-dom@17/umd/react-dom.production.min.js" crossorigin></script> <script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script>
3つのScriptこれは『Reactの本体』・『DOM操作用react-dom』それに加えて『JSのトランスコンパイラ』である『Babel』を読み込んでいます。
そして次なんですが、1番気をつけてほしいポイントとなります。
scriptタグにtext/babelと記述します、でないとせっかく書いたコードが読み込まれなくなってしまいます
なぜこう書くかはJSXがBabelによってJavascriptにコンパイルされるからです、そしてHTMLがJSを読み込む仕組みとなっております。
<script src="/" type="text/babel">
このようにお願い致します。
こちらでも確認できますので、視聴下さい。
当ブログでのURLを知ってる方のみの限定公開となります。
※公開してYouTubeしていく予定はございません。
これで、準備は終わりです!
このCDNの@17、これはバージョンになりますなのでもし途中で読み込まれなかったら両方とも@16とかにダウングレードしてみて下さい。
実際にクラスをつかってみる
簡単な実装です、ボタンタグでカウントアップです
class App extends React.Component { constructor(props) { super(props); this.state = { counter: 0 //初期値はゼロ } } render() { return( <div> <button onClick={ () => this.setState({ counter: this.state.counter + 1})}>count up { this.state.counter } </button> </div> ) } } ReactDOM.render( <App />, document.getElementById("root") );
Class Componentの仕組み
まずAppという名のコンポーネントを定義するんですが、Reactコンポーネントクラスを定義するには、
『React.Component』を継承する必要があります。
なのでReactで作られたコンポーネントを元にしている『extends』で拡張(継承)します
その後『constructor』で初期化し引数である『props』を渡します、propsは親コンポーネントから子のコンポーネントへ渡すものだと思って下さい。
『super』とはReact.Componentの事を指しておりスーパークラスなどと言ったりしますおまじないみたいなもんです、こちらも引数としてpropsを渡す。
class App extends React.Component { constructor(props) { super(props); this.state = { counter: 0 } } }
『this.state』内ではコンポーネントの中だけで値を管理をしてくれる変数だと思ってください、そしてコンポーネントの中だけで使えるstateをローカルstateと言います。
super(props)を定義してからでないと、this.state内の新規追加の値は変更できません。
renderメソッド内でJSコードを記述していきrender内でJSXをreturn(返します)。
class App extends React.Component { constructor(props) { super(props); this.state = { counter: 0 //初期値はゼロ } } render() { return( <div> <button onClick={ () => this.setState({ counter: this.state.counter + 1})}>count up { this.state.counter } </button> </div> ) } } ReactDOM.render( <App />, document.getElementById("root") );
this.state内でcounterとし初期値の0を設定し
onClickのイベントハンドラーを使用します、ですがこのままだと初期値がゼロのままです
数字の値を変更しなければいけないのでReactのクラスコンポーネントを使用する際は『setState()』メソッドを使い、値の変更をしていきます、後は単純な加算するだけです。
そしてReact 要素をルートDOMノードにレンダーするにはReactDOM.render()に渡してあげないといけません。
ReactDOM.render(
React-Routerを導入
それではクラスの次はFunctional Componentなんですが
関数型はあまり覚える所が少ないのでご自身でやってみてください!軽く解説していきます。
関数型のコンポーネントで基本的にはアロー関数を使用し定義します。
ここでCDN『script』を入れ替えてください
<head> <script src='https://unpkg.com/react@16.3.1/umd/react.production.min.js'></script> <script src='https://unpkg.com/react-dom@16.3.1/umd/react-dom.production.min.js'> </script> <script src='https://unpkg.com/react-router-dom@5.0.0/umd/react-router-dom.min.js'></script> <script src='https://unpkg.com/babel-standalone@6.26.0/babel.js'></script> </head>
body内は先程と同じで構いません。
ここからはコード分割で説明はさみながらいきます
まずは全体のコードをどうぞ
<body> <div id='root'></div> <script type='text/babel'> const Link = ReactRouterDOM.Link; const Route = ReactRouterDOM.Route; const App = () => ( <ReactRouterDOM.HashRouter> <ul> <li><Link to="/">Home</Link></li> <li><Link to="/about">About</Link></li> <li><Link to="/contact">Contact</Link></li> </ul> <Route path="/" exact component={Home} /> <Route path="/about" component={About} /> <Route path="/contactr" component={Contact} /> </ReactRouterDOM.HashRouter> ) const Home = () => <h1>Home</h1> const About = () => <h1>Aboutページ</h1> const Contact = () => <h1>Contactページ</h1> ReactDOM.render(<App />, document.getElementById("root")); </script> </body>
普段のreact-routerと変わらない、ですが今はreact-routerのバージョンアップにより現在ではこの書き方とは少し変わっています。では分割しながら説明致します。
まずはこちら
const Link = ReactRouterDOM.Link; const Route = ReactRouterDOM.Route;
本来のReactで書き直すと
import {Route, Link, …} from 'react-router-dom';
ただインポートして読み込むだけとなりますこのimport用を、グローバルオブジェクトのプロパティとして呼び出し、それを使用する為に変数に入れてます。
const App = () => { <ReactRouterDOM.HashRouter> <ul> <li><Link to="/">Home</Link></li> <li><Link to="/about">About</Link></li> <li><Link to="/contact">Contact</Link></li> </ul> </ReactRouterDOM.HashRouter> }
const App = () => これが名前通り関数型のコンポーネントとなります、クラスに比べて覚える所が少なすぎますね。
このReactRouterDOM.HashRouterはHashRouterコンポーネントに呼び出されたReactRouterDOMのグローバルオブジェクトになります。
そしてLinkのtoはHTMLのaタグと似たような動作となりますのでURLとなります
違いとしてはaタグは外部でLinkは内部のみ
RouteではURL(ルーティング先)のURLと一致した時に描画させるコンポーネントの指定がpatchとなる。
const Home = () => <h1>Home</h1> const About = () => <h1>Aboutページ</h1> const Contact = () => <h1>Contactページ</h1>
これはページ遷移先である子のコンポーネントで変数として入れ込み、ルートが要求される度に別々のコンポーネントを描画します。
DEMO
上のURLの所を見て頂ければ分かると思いますが
一致したURLにしっかりとページ遷移されています。
内部で切り替わってるだけのリンクですが、あたかも外部の複数ページがあるように見えますね!これがReact-Routerです。
HTMLで導入してもさすがです、ページ遷移が高速です。