reactnative

React Native勉強メモ 〜Componentの基礎編〜

はじめに

React Nativeの勉強した際のメモ。
今回はComponentの基本的な使い方について。

バージョン:React Native 0.46

アプリのエントリーポイント

index.jsでAppRegistryにエントリーポイントとなるComponentを登録する。

//第1引数はComponent名と同じ文字列、第2引数はFunctionでComponentを返す。
AppRegistry.registerComponent('<Component名>', () => <Component>);

OSごとに処理を分ける

  • ファイル名で分ける
    xxx.android.js
    xxx.ios.js

  • ソースコード中で分ける
    Platfom.OSで判別可能

import { Platform } from 'react-native';

if(Platform.OS === 'android'){
  //Android向けの処理
}else if(Platform.OS === 'ios'){
  //iOS向けの処理
}

Componentの書き方

  • モジュールのimport

reactの"Component"および使いたいViewモジュールをimportしておく。
Styleを定義するために、StyleSheetもimportする。

index.xxx.js
import React, { Component } from 'react';
import { StyleSheet, View, Text, ... } from 'react-native';
  • Componentを継承したクラスを実装する

ES2015のclassシンタックスでReactのComponentを継承したクラスを作成。
export defaultを付けて公開すると、他のモジュールからimportできるようになる。
初期化処理はConstructor(props)を使う。

(ググるとcreateClass(), getInitialState()みたいな記述も見つかるが、こちらは古い書き方)

export default class Hoge extends Component{
  //コンストラクタ
  constructor(props){
    super(props); //必ず呼ぶ
  }

  render(){
    let hoge = {text:'piyo'};

    return(
      //レイアウトのJSXでReactNativeのViewを配置
      //JSX内で変数を使う場合は、{}でくくる
      <View style={styles.container}>
        <Text>{hoge.text}</Text>
      </View>
    );
  }
}

//スタイル定義
const styles = StyleSheet.create({
  container: {
    width: 100,
    height: 44,
    ...
  }
});

Componentのプロパティ (props)

親から渡されるimmutableなデータ。
コンポーネント内で値を書き換えない。
xxx='hoge'のようにタグの属性として使う。
変数を使うときは{}でくくる。

  • Component側
Greeting.xml
<Text>Hello {this.props.name},</Text>
  • 使い方
<Greeting name='Taro' />
<Greeting name={user.name} />

prop-typesライブラリを使うと型チェックしてくれて安心。
https://github.com/facebook/prop-types

プロパティをイベントハンドラとして使う

また、イベントを親に伝える際に、propsでハンドラを渡す方法が使える。

  • Component側
MyButton.js
//onPressイベントで、親から貰ったprops.onClickが呼ばれる
<Button onPress={this.props.onClick} />
  • 使い方
_onClick(){
  console.log('Clicked!!!');
}

<MyButton onClick={this._onClick} />

Componentの状態 (state)

Component内部で保持している状態を管理するオブジェクト。
Component内で使い、他のComponentとやりとりしない。

stateの値を書き換えるにはsetState()メソッドを使う。
setState()すると、勝手にrender()が呼ばれてComponentが再描画される。

Component内での関数定義について

Component内で自作の関数を定義すると、関数内のthisはグローバルオブジェクトを指す。
そのため、そのままthis.props.hogeを参照してもundefinedになってしまう。
そこで、メンバ関数のbind(this)を呼んでComponent自身がthisになるように指定しておく。
または、アロー関数にしておいて、参照元がthisとなるように仕向けても良い。

ライフサイクル

Componentのライフサイクル 。
ネイティブのViewのライフサイクルとは別。

  • constractor(props)
    Componentのマウント前に1度だけ呼ばれる
    super(props)を必ず呼ぶこと
    stateの初期化を行う

  • componentWillReceiveProps(object nextProps)
    新しいpropsを受け取ったときに呼ばれる
    propsに応じてsetState()できる。

  • render()
    描画する要素を返す。
    ここでsetState()してはいけない。

  • componentDidMount()
    render()した後で呼ばれる

  • componentWillUnmount() アンマウント時に呼ばれる リソースの開放など

setState()されて更新する場合はrender前後で以下が呼ばれる。

  • componentWillUpdate(object nextProps, object nextState)
    状態更新時に、render()の直前に呼ばれる
    ここでsetState()してはいけない。

  • componentDidUpdate(prevProps, prevState)
    更新時にrender()の後に呼ばれる。

ライフサイクルについては、こちらの投稿がとてもわかりやすかったです。
http://qiita.com/kawachi/items/092bfc281f88e3a6e456
http://qiita.com/yukika/items/1859743921a10d7e3e6b

おわりに

React NativeでComponentを書くために最低限必要な情報をまとめました。
役割が明確なpropsとstateのおかげで、慣れてしまえばネイティブよりも機械的にサクサク実装できて良い感じです。