はじめに
こんにちはnukkyです。
今回は改めてReact Nativeの入門として必要そうなことをおさらいがてらまとめました。
そもそもReact Nativeとは
React Native は、Facebook社が開発・公開しているネイティブアプリのクロスプラットフォーム開発フレームワークです。言語としてJavaScriptを使用し、Reactを触ったことがある人であれば気軽にモバイルアプリ開発を始められます。
React Nativeは、プログラミング言語として主にJavaScriptでコーディングをしていきます。そのため、JavaScriptの知識が必要です。
JSXとは
JSXはJavaScriptにXMLライクのシンタックスを追加する言語拡張です。JSXを使うと、JavaScriptコード中にHTMLタグを埋め込んでいるかのように記述できます。
ReactおよびReact Nativeでは機能をコンポーネント単位で管理しますが、コンポーネントを使う場合はJSXを使って書きます。
下記コードでは View というコンポーネントの中にTextというコンポーネントを置いています。Viewは要素を描画するためのコンポーネントで、HTMLで言うところのdivやspanにあたります。
1 2 3 | <View> <Text>Hello world!</Text> </View> |
JSXに値を埋め込む
JSXはタグをそのまま表示するだけではなく、JSXの中にJavaScriptの値を埋め込むことも出来ます。以下のような形で記述します。
1 | { 変数や値など } |
このように{}の中に変数などを記述することで、その変数の値をJSXの中に埋め込むことができるようになります。実際の記述は以下のようになります。
1 2 3 4 5 6 7 8 9 10 | render() { let title = "タイトル"; let message = "メッセージ"; return ( <div> <h2>{title}</h2> <p>{message}</p> </div> ); } |
ここで一つ注意して欲しいのが上記JSXをdivタグで囲っていることです。理由としては、renderメソッドは1つのエレメントのみという制約があります。divタグを外してしまうとエレメントが2つになってしまいエラーになってしまいます。
属性の値を設定する
{}による埋め込みは、テキストコンテンツのみだけではなく他の箇所にも使用することができます。例えば、タグの属性の値にも使用することができます。
1 2 3 4 5 6 7 8 9 10 | render() { let title = "タイトル"; let link = "https://google.com"; return ( <div> <h2>{title}</h2> <p><a href={link}>this is link</a></p> </div> ); } |
このようにaタグのhref属性に{}で変数を設定することができます。
関数でJSXを作る
JSXの値は、変数などに代入して使用するだけではなく、普通の値として様々なところに利用することができます。計算の式や関数、オブジェクトのメソッドなどの中にもJSXは利用できます。
例えば関数の戻り値でJSXをreturnすれば、様々なタグを生成する関数を用意することができます。上記のサンプルコードを以下のようにすることもできます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | returnLinkJsx() { let link = "https://google.com"; return <p><a href={link}>this is link</a></p>; } render() { let title = "タイトル"; return ( <div> <h2>{title}</h2> {this.returnLinkJsx} </div> ); } |
コンポーネントとは
コンポーネントとは、画面に表示される部品のようなものです。表示の内容やデータ、処理などを一つのオブジェクトにまとめたものです。React Nativeでは、このように自分で作ったコンポーネントや、もともとあるTextなどのコンポーネントを組み合わせて、画面のUIを組み立てていきます。
再利用性
React Nativeのコンポーネントの大きな特徴として、再利用可能であることが挙げられます。
たとえば、アプリにはどの画面にも共通のパーツがあると思いますが、そのパーツをコンポーネントとして一箇所で実装し、他のところから参照することで、同じコードを繰り返して書かずに済みます。
新規コンポーネントの作成
プロジェクトのsrc/components/sample.jsを作成し以下のコードを記述します。
1 2 3 4 5 6 7 8 9 10 11 | export default class Sample extends Component{ render() { return ( <View> <Text> Hello Component </Text> </View> ); } } |
これでコンポーネントができました。export defaultで宣言したことにより他のモジュールからimportできるようになります。
export default class
そのclassがimportされるときにdefaultで呼ばれるクラスになります。
1 2 | // このとき自動的にdefault classが呼ばれる import Sample from './src/components/sample' |
defaultをつけない場合クラスを指定してimportします。
1 | import {Sample} from './src/components/sample' |
コンポーネントの呼び出し
Hello WorldにSampleクラスをimportして呼び出したいと思います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | import React, { Component } from 'react'; import { Text, View } from 'react-native'; /* Sampleのコンポーネントをimportする。App内にSampleタグを追加する。*/ import Sample from './src/components/sample' export default class HelloWorldApp extends Component { render() { return ( <View> <Sample /> <Text>Hello world!</Text> </View> ); } } |
Sampleをimportしたので<Sample />これだけでコンポーネントの呼び出しが可能になります。
PropsとState
Props
React Nativeではアプリをコンポーネント単位で管理しますが、Propsとはコンポーネントと外部とのインターフェースであり、コンポーネントに必要な値を受け取ることができます。
状態によって値が変わるようなものはStateに任せるため、Propsはimmutableで変更してはいけません。
React Nativeの標準として提供されるコンポーネントにもPropsは定義されているので、コンポーネントの使用時にカスタマイズできます。また自分でコンポーネントを作る際にも、Propsを定義することでカスタマイズ可能な状態にすることができます。
1 2 3 4 5 6 7 8 9 10 11 12 | class Greeting extends Component { render() { <div> <Hello name="react" /> <p>Happy hacking!</p> </div> } } const Hello = (props) => { return <p>Hello, {props.name}!</p>; } |
State
Propsはimmutableでコンポーネントの属性を保管しておくものでしたが、それに対してStateはコンポーネントの状態を表す値を保管するものになります。
これは、コンポーネントの現在の状態を扱うためのものです、つまりStateの値を操作することでコンポーネントの状態を操作します。
コンポーネントの表示の変更など必須とも言える機能になります。
Stateを用意する
Stateはコンポーネントに「state」というプロパティとして用意されます。この中にStateの値がまとめて保管されます。まずはconstructorで値を初期化します。
1 2 3 4 5 6 7 | constructor(props) { super(props); this.state = { value1: 'foo', value2: [ 'bar', 'baz' ], }; } |
Stateの値を表示する
初期化したStateは「this.state.〜」で扱うことができます。
1 2 3 4 5 6 7 | render() { return ( <div> <h1>{this.state.value1} </h1> </div> ); } |
Stateの値を更新する
ここからがStateのキモの部分である状態の変更・更新になります。Stateの更新は「this.setState」で行います。Stateの状態を変える時には必ずsetStateメソッドを使って変える必要があります、setStateメソッドを呼ぶとrenderメソッドが必ず呼ばれるので画面の表示の更新もそのまま行ってくれます。
1 2 3 4 5 6 7 | render() { return ( <div onClick={() => this.setState({ value1: 'bar' })}> <h1>{this.state.value1} </h1> </div> ); } |
イベントハンドリング
上記のようなコードの場合onClickからメソッドを呼び出したいと思います。その場合は明示的にクラスメソッドをバインドする必要があります。上記のコードを元にconstructorでdoActionメソッドをバインドしonClickで呼び出したいと思います。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | constructor(props) { super(props); this.state = { value1: 'foo', value2: [ 'bar', 'baz' ], }; this.doAction = this.doAction.bind(this); } doAction(e) { this.setState({ value1: 'bar' }) } render() { return ( <div onClick={this.doAction}> <h1>{this.state.value1} </h1> </div> ); } |
さいごに
自分も基礎的な部分の理解がおろそかだったので入門として復習がてら記事にさせてもらいました。今後もReact Nativeの勉強を続けていき記事にするのでよろしくお願いします。