JSXとは?
JavaScript XMLの略でJavaScriptを拡張した言語でテンプレート言語の一つです。Facebook社が開発しました。
メリット
見た目がHTMLやXML風なので可読性が非常に高いです。
仕組み
アプリケーション内でトランスパイルが行われてJavaScriptコードに変換されます。
変換例
JSX変換前
1 2 3 4 5 6 7 8 9 10 11 |
import React from 'react'; function App() { return React.createElement( "div", null, "Hello, world" ); } export default App; |
JSX変換後
ソースがこんなに短くなります。
1 2 3 4 5 |
function App() { return <div>Hello World!</div >; } export default App; |
JSXのルール
JavaScriptを埋め込むことができる。
{}を使うことで文字列、数値、関数などを埋め込むことができます。
1 2 3 4 5 6 7 |
function App() { const message = 'test'; return ( <div>{message}</div > ) } |
一つのタグで囲ってないといけない。
必ずjsxは一つのタグで囲っていないとダメです。エラーになってしまいます。下記のようにdivなどで囲うようにしましょう。
1 2 3 4 5 6 7 |
function App() { return ( <div> <label htmlFor="bar">bar</label> </div > ) } |
ただ、これだと余計なdivが一つ増えてしまいますので下記のようにReact.Fragmentというタグを使って記述します。そうすることで余計なタグが増えません。
1 2 3 4 5 6 7 |
function App() { return ( <React.Fragment> <label htmlFor="bar">bar</label> </React.Fragment> ) } |
もしくは下記のようにも書けます。
1 2 3 4 5 6 7 |
function App() { return ( <> <label htmlFor="bar">bar</label> </> ) } |
全てのタグを閉じる必要がある。
例えば、<br>は通常のHTMLでは閉じる必要はないですが、<br />と記述する必要があります。
全てのHTMLタグは利用できない後述する代替タグがある。
className
1 2 3 |
function App() { return <div className="test">Hello World!</div >; } |
htmlFor
for属性もJavaScriptのforと被るのでhtmlForと記述します。
1 2 3 4 5 6 7 |
function App() { return ( <div> <label htmlFor="bar">bar</label> </div > ) } |
Component
ReactのComponentには2種類あります。今はファンクショナルComponentで作るのが普通です。
- ファンクショナルComponent
- クラスComponent
コンポーネントの規則
コンポーネント名の先頭文字は必ず大文字にする必要があります。
ファンクショナルComponent(関数コンポーネント)
実質関数を定義しているだけです。
1 2 3 |
const App = () => { return <div>Hello World!</div> } |
returnとしてJSXを返します。アロー関数を使わずに下記のように記述することも可能です。
1 2 3 |
function App() { return <div>Hello World!</div> } |
メリット
- 無駄なライフサイクルがないので、クラスコンポーネントに比べてレンダリングのパフォーマンスが良い。(6%ほど高速化できるらしい。)
- stateを保持できないが、Hooksの登場によって保持できるようになった。
クラスComponent
AppというクラスにComponentを継承させています。
1 2 3 4 5 6 7 8 9 |
import React, { Component } from 'react'; class App extends Component { render() { return ( <div>Hello World!</div> ) } } |
Componentのimportも忘れずに行う必要があります。
State
Componentが持っている状態のことでコンポーネントの内部でのみ利用されます。propsが変更不可能なイミュータブルな値だったのに対して、Stateは変更可能なミュータブルな値です。クラスComponentで利用できる機能です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
import React, { Component } from 'react'; const App = () => (<Counter></Counter>) class Counter extends Component { constructor(props) { super(props) this.state = { count: 0 } } render() { return (<div>count: { this.state.count}</div>) } } |
constructorでstateを初期化してrenderの中でその値を読み込むことが可能です。
Stateの更新処理
下記のようにメソッドを作ってstateを更新するようにもできます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
import React, { Component } from 'react'; const App = () => (<Counter></Counter>) class Counter extends Component { constructor(props) { super(props) this.state = { count: 0 } } plus = () => { this.setState({ count: this.state.count + 1 }) } render() { return ( <React.Fragment> <div>{this.state.count}</div> <button onClick={this.plus}>plus</button> </React.Fragment> ) } } |
なお、stateをいじる際は必ずsetStateを使って更新しなければならないです。(直接更新しようとするとエラーになります。)、理由としてはsetStateの仕組みとして状態を変更するのと同時に画面の再描画を行ってくれるためです。
裏側の仕組みとしてはsetStateのコールバックとしてrenderメソッドが実行されています。
この記事へのコメントはありません。