React 基礎編
React備忘録
目次
- ReactDOM.render( )
- JSX
- Component
今回はReact.jsの記事になっています。
Reactの導入についてはいろんなとこで紹介されているので今回は省略させてもらいます。
今回はこんなのを作っていこうと思います。
各色がクリックされる度にトータルの数が増えていく、というような機能ですね。
では見ていきましょう。
ReactDOM.render( )
まずはベースとなるファイルです
index.html
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <link rel="stylesheet" href="css/styles.css"> <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://unpkg.com/@babel/standalone/babel.min.js"></script> </head> <body> <script> </script> </body> </html>
headタグ
内にあるscriptタグ
3つはReactのCDNを使用するための記述です。
そして、一般的なjsと同じようにbodyタグ
内にscriptタグ
を用意し、スクリプトを書いていきます。
・・・
今思ったけどこの記事めちゃめちゃ長くなるかも・・・
まあ、やっていきましょう。
まずは処理全体を即時関数で囲いたいので、ES6のアロー関数で書いていきましょう。
ここからはbodyタグ内のみ書いていきますね。
<body> <script type="text/babel"> (() => { })(); </script> </body>
即時関数
とは無名関数を定義と同時に実行する関数のことです。
補足ですが、scriptタグのtype属性がtext/babel
となっています。これはhtmlファイル9行目、スクリプトタグ3つ目のbabel
というライブラリを使用するために書いています。
babel
を用いることで、JSX
やJavaSvript
の新しい記法を使うことができます。
次にUIを表示する領域を作っていきます。
まずはdiv要素を作ります
<body> <div id='root'></div> <script type="text/babel"> (() => { })(); </script> </body>
そしてReactで作った部品を描画していきます。
<body> <div id='root'></div> <script type="text/babel"> (() => { ReactDOM.render(); })(); </script> </body>
このように関数内でReactDOM.render();
とします。
次に第一引数に描画したいUIをJSX
という記法を用いて書き、第二引数にはそのUIをどこに描画したいのかを記述します。
(() => { ReactDOM.render( <p>Hi!</p>, document.getElementById('root') ); })();
このように第一引数はHTMLと同じように要素を書きます。
第二引数ではjsの書き方で、idがroot
の要素を取得しています。
なので今回の場合は
p要素のHi!
という文字列を、 getElementById で取得したidがroot
の要素に描画するという処理になっています。
JSX
JSX
には{ }
を使用することでJavaScriptを埋め込むことができます。
ではJSXをもう少し詳しく見ていくために、定数を定義し、埋め込みます。
(() => { const name = 'TomozQoo' ReactDOM.render( <p>Hi!{name}</p>, document.getElementById('root') ); })();
{ }
内をname
としてJavaScriptを埋め込んでいます。
ちゃんと表示されていますね。
ちなみにメソッドもちゃんと使用することができます
(() => { const name = 'tomozqoo' ReactDOM.render( <p>Hi!{name.toUpperCase()}</p>, document.getElementById('root') ); })();
{ }
内でtoUpperCase( )
とすることで全て大文字で出力されていますね。
そして、注意点なのですが、JSXで渡せる要素は1つという決まりがあります。
なので
(() => { const name = 'tomozqoo' ReactDOM.render( <p>Hi!</p>, <p>{name.toUpperCase()}</p>, document.getElementById('root') ); })();
このようにp要素を2つ渡そうとするとエラーが出てしまいます。
今回のようにp要素を2つ渡したい場合には
(() => { const name = 'tomozqoo' ReactDOM.render( <div> <p>Hi!</p> <p>{name.toUpperCase()}</p> </div>, document.getElementById('root') ); })();
このように1つの要素で囲ってあげる必要があります。
結果はこうです。
またHTMLには閉じタグがない要素もあります。
例えばhr
要素なんかがそうですね。
(() => { const name = 'tomozqoo' ReactDOM.render( <div> <p>Hi!</p> <hr> <p>{name.toUpperCase()}</p> </div>, document.getElementById('root') ); })(); </script> </body>
そのまま書いてしまうと、このように閉じタグが無いよというエラーが出てしまいます。
その場合には
<div> <p>Hi!</p> <hr/> <p>{name.toUpperCase()}</p> </div>,
このようにタグを閉じてあげればOKです。
ではさらに詳しくJSXを見ていきましょう。
<body> <div id="root"></div> <script type="text/babel"> (() => { ReactDOM.render( <div></div>, document.getElementById('root') ); })(); </script> </body>
まずはクラスについてです。
HTMLだとクラスを指定するには
<div class='test'></div>
とかって書きますよね。
ただ、JavaScriptだとclassは予約語になっています。
class App{ }
こんな感じで使いますよね。
なのでJSXで要素のクラスを指定するには違う名前を使わなくてはならず、
className
というのを使います。
<body> <div id="root"></div> <script type="text/babel"> (() => { ReactDOM.render( <div className='box'></div>, document.getElementById('root') ); })(); </script> </body>
class
と書いていたところをclassName
にしてあげるだけですね。
ではCSSでboxクラスの見た目を整えていきます。
.box{ width: 100px; height: 100px; background: skyblue; }
こんな感じ。ちゃんと適用されてますね。
また、直接スタイルを指定することもできます
ReactDOM.render( <div style={{width: 100, height: 100, backgroundColor: '#FF3333'}}></div>, document.getElementById('root') );
スタイルはオブジェクト形式
で指定する必要があるので、まず{ }を書き、その中にプロパティが入ったオブジェクトを書いていきます。
そのため{{ }}
の様になります。
また、属性についてはcamelCase
で書く必要があるのでCSSではbackground-color
としているところJSXではbackgroundColor
と書きます。
px
も省略することができます。
こんな感じですね。
では次にイベントを設定してみます。
この箱がクリックされたらアラートが出る様に設定してみましょう
まず関数を作ります。
<body> <div id="root"></div> <script type="text/babel"> (() => { function showMessage(){ alert('success!!'); } ReactDOM.render( <div style={{width: 100, height: 100, backgroundColor: '#FF3333'}}></div>, document.getElementById('root') ); })(); </script> </body>
次にイベントを発火させる処理を書いていきましょう。
Reactでは要素に直接イベントを書くことが多い様です。
なので
<body> <div id="root"></div> <script type="text/babel"> (() => { function showMessage(){ alert('success!!'); } ReactDOM.render( <div style={{width: 100, height: 100, backgroundColor: '#FF3333'}} onClick = 'showMessage'></div>, document.getElementById('root') ); })(); </script> </body>
としたいところですが、これだとエラーが出てしまいます。
String型ではなく、関数をちょうだい!!ってエラーですね
JavaSvriptの式は{ }で渡さなくてはいけないので
ReactDOM.render( <div style={{width: 100, height: 100, backgroundColor: '#FF3333'}} onClick = {showMessage}></div>, document.getElementById('root') );
とします。
こんな感じですね。
Component
ここではComponent
と呼ばれる独自のタグを使って、様々な機能を追加していってみます。
下記はベースのコードです。
<body> <div id="root"></div> <script type="text/babel"> (() => { ReactDOM.render( <div></div>, document.getElementById('root') ); })(); </script> </body>
では見ていきましょう。
ReactDOM.render( <Counter/>, document.getElementById('root') );
こんな書き方でコンポーネントは作ることができます。
1文字目は必ず大文字にしなくてはなりません。
次にコンポーネントを定義していきます。
JSの関数で定義します。
(() => { function Counter(){ } ReactDOM.render( <Counter/>, document.getElementById('root') ); })();
こうですね
では中身を返す関数にしましょう。
function Counter(){ return <div>0</div>; }
ちゃんと0が表示されてますね!
Counterを増やしましょう
ReactDOM.render( <div> <Counter/> <Counter/> <Counter/> </div>, document.getElementById('root') );
JSXでは要素を一つしか返せないのでdivタグで囲ってあげます。
結果はこんな感じです。0が3つできました。
また、コンポーネントごと大枠の内容は一緒なんだけど微妙に変えたいということもできます。
その場合にはコンポーネントに属性をつけてあげます。
ReactDOM.render( <div> <Counter color='#FF3333'/> <Counter color='#FFFF55'/> <Counter color='#4689FF'/> </div>, document.getElementById('root') );
属性の名前は何でも大丈夫です。今回はcolorとして値に色を入れています。
そしたらコンポーネントでこの値を取ってみましょう
引数を指定します。
function Counter(props){ return <div>{props.color}</div>; }
引数をprops
として{props.color}
で要素のカラー属性の値を取得しています。
ここで注意なのですが、この引数である props は読み取り専用になっています。
なので
function Counter(props){ props.color = 'red'; return <div>{props.color}</div>; }
としても
この様に、読み取り専用のプロパティだよというエラーが出てしまいます。
ではCounterが色を取得できたので、背景色を変えてみましょう。
(() => { function Counter(props){ return <div style={{backgroundColor: props.color}}>0</div>; } ReactDOM.render( <div> <Counter color='#FF3333'/> <Counter color='#FFFF55'/> <Counter color='#4689FF'/> </div>, document.getElementById('root') ); })();
こんな感じです。ちょっとだけそれっぽくなってきました!
では最後にちょろっとスタイルを整えます。
<body> <div id="root"></div> <script type="text/babel"> (() => { function Counter(props){ return <li style={{backgroundColor: props.color}}>0</li>; } ReactDOM.render( <div className='container'> <ul> <Counter color='#FF3333'/> <Counter color='#FFFF55'/> <Counter color='#4689FF'/> </ul> </div>, document.getElementById('root') ); })(); </script> </body>
まずはJSXでCounterをリストにして、横並びにしたいのでdiv要素にcontainerというクラスをつけました。
そして返す要素をdiv要素からli要素に変更です。
こんな感じですね。
ではCSS
body{ font-size: 16px; font-family: Verdana, sans-serif; } .container{ width: 330px; margin: 20px auto; } .container ul{ list-style: none; margin: 0; padding: 0; display: flex; flex-wrap: wrap; } .container li{ width: 100px; height: 100px; line-height: 100px; text-align: center; cursor: pointer; user-select: none; border-radius: 50%; margin: 0 5px 10px 0; }
CSSの説明は割愛します。
こんな感じです!
今回はここまで
続きは次回!
それではまた!