SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

基礎からはじめるReact Native入門

Reactの基本を学ぼう~コンポーネントで動的な状態管理

基礎からはじめるReact Native入門 第4回

  • X ポスト
  • このエントリーをはてなブックマークに追加

ユーザー操作のイベントを使って状態を更新する

 それでは、stateの具体的な使い方について例を挙げていきましょう。まずはユーザー操作を受け付けて状態を変更する方式をサンプルにします。単純なほうがよいので、ボタンを押すと数字が増減するカウンターアプリにしてみましょう(図2)。

図2:カウンターアプリ
図2:カウンターアプリ

 ソースコードはリスト6のとおりです。

[リスト6]カウンターアプリ
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';

export default class App extends React.Component {
  constructor(props) {
    super(props);

    this.state = {
      count: 0,
    }
  }

  onPressMinusOne = () => {
    this.setState({ count: this.state.count - 1 }); // (2)
  };

  onPressPlusOne = () => {
    this.setState({ count: this.state.count + 1 }); // (3)
  }

  render() {
    return (
      <View style={styles.container}>
        <Button title="-1" onPress={this.onPressMinusOne} />{/* (1) */}
        <Text>{this.state.count}</Text>
        <Button title="+1" onPress={this.onPressPlusOne} />
      </View>
    );
  }
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    flexDirection: 'row',
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  }
});

 React Native標準のButtonコンポーネントを使ってみました。React Nativeはモバイルアプリ開発のツールである都合上、画面はクリックするものではなくタップするものという前提があります。そのため、タップイベントを受け取るためのpropsの名前はonclickonClickではなく、onPressになっています。

 onPressは関数オブジェクトを受け取るpropsです。(1)のように、関数オブジェクトを登録しておくと、タップイベントが発生したときにその関数が実行されます。今回の例ではクラスのプロパティであるonPressMinusOneonPressPlusOneを実行するようにしてみました。その内部では(2)や(3)のようにsetStateを呼び出しており、ボタン操作によってstateを更新する流れが作られています。

関数を扱うpropsの注意点

 リスト6では、クラス内の関数の定義とJSXの組み合わせが、リスト7のようになっていました。

[リスト7]クラスのプロパティとして関数を登録する
// 関数定義
onPressMinusOne = () => {
  this.setState({ count: this.state.count - 1 });
};
// JSX
<Button title="-1" onPress={this.onPressMinusOne} />

 この関数定義は、ECMAScriptのクラスにおけるメソッド定義の文法ではなく、プロパティにラムダ記法で記述された関数を代入する式です。本来は、リスト8のような書き方をしたほうが、クラスの使い方として直感的です。

[リスト8]誤った関数オブジェクトの渡し方
// 関数定義
onPressMinusOne() { // (1)
  this.setState({ count: this.state.count - 1 }); // (3)
};
// JSX
<Button title="-1" onPress={this.onPressMinusOne} /> // (2)

 では、なぜリスト7のような面倒なことをしているのかというと、リスト8の書き方は意図しない動作をする可能性があるからです。

 実は、(1)のようにクラス内に定義されたメソッドであっても、その中で使われるthisの参照先は実行方法によって変わってしまうのです。(2)のように関数オブジェクトをそのまま渡すと、実行時に(3)がthisとして参照するのはButtonコンポーネントになります。そのため、リスト8の形で実装したアプリを起動して、マイナスボタンを押すと、図3のようなエラーが発生します。

図3:thisの参照ミスによりエラーが発生する
図3:thisの参照ミスによりエラーが発生する

 図3上部の赤いところを参考にして状況を読み取ってみると、Buttonコンポーネントの中にthis.stateが存在しない、つまりundefinedなので、その中のcountを参照しようとした時点でエラーになる、ということです。これはReactの仕組み上そうなっているわけではなく、ECMAScriptのクラス記法の標準的な仕組みで起こる課題です。

 どうしてもメソッド記法を使いたい場合は、リスト9のように記述することができます。

[リスト9]メソッド記法を使いたい場合
// コンストラクタ
constructor(props) {
  super(props);
  this.onPressMinusOne = this.onPressMinusOne.bind(this); // (1)
}
// 関数定義
onPressMinusOne() {
  this.setState({ count: this.state.count - 1 });
};
// JSX
<Button title="-1" onPress={this.onPressMinusOne} />

 (1)のように事前にthisをバインドしておくことで、thisAppにひも付けておくことができます。しかし面倒なので、ひとまずリスト7の方法を覚えておくとよいでしょう。

次のページ
ライフサイクルを使って状態を更新する

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
基礎からはじめるReact Native入門連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 中川幸哉(ナカガワユキヤ)

WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS Twitter: @yyamada(公式)、@yyamada/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/11748 2019/10/15 11:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング