【React Native】Stateとは?
この記事の内容
Stateとは?
Stateはコンピューターサイエンスでよく使われている単語で「状態」の意味です。イベントが覚えているシステムでその覚えていることがState(状態)です。Stateはシステムのメモリみたいなコンセプトです。
React Nativeのコンポーネントは2種類のデータがあります。propsとStateです。propsは一回代入した後で変更できませんが、Stateを使ったら表示していることが変更できます。React Nativeの基礎の中でStateは一番難しいですが、Stateで動的なアプリが色々作れます。
propsについては下記の記事を参考にしてください。
Stateの使い方
1.Stateの初期化
export default class App extends Component { state = {data: ""}; }
classの中でStateを代入します。上記の場合はStateのdataは空白文字列に初期化します。下記のようにStateのプロパティは何個でも使えます。
state = { superpower: "", mood: "" }
2. Stateを読む
同じクラスであればthis.stateでStateの値が読めます。
上記の例はこのコードで値が使えます
this.state.superpower this.state.mood
3. Stateをセットする
Stateの値を更新する時にはthis.setStateを使います。
state.superpowerを更新する(他のプロパティはそのまま変わりません)
this.setState({superpower: "飛行"});
this.setStateを呼び出したら、renderは再実行されます。
もしthis.setStateではなく、this.state を直接更新したら(this.state に代入したら)renderが実行されないので、初期化の時以外はthis.stateに代入しないように気を付けてください。
複数の場合
this.setState({ superpower: "飛行", mood: "わくわく" });
次のStateが前のStateと関係ある場合
Stateは前値を使って新値を決める時があります。例えば、Stateの値が数字であれば次の値は前の数字から計算することが多いです。この場合は2つの方法があります。下記のAとBのコードを見ましょう。
A. ×
this.setState(this.state.count+1)
B. 〇
this.setState((state, props) => { let nextCount = state.count + 1; return {count : nextCount}; });
Aは普通のthis.setStateの使い方ですが、問題があります。this.setStateは非同期な関数なので、同じタイミングでthis.setStateを複数呼び出した時this.stateを確認したら新しい値がまだ代入されてない可能性があります。Bの場合はStateが正しい値です。
Bのthis.setStateの引数は関数です。関数は第一引数が現在のState、第二引数がpropsで戻り値は次のStateです。
使用例
例1:入力されたテキストを表示する
最初はTextでTextInputのテキストを表示するシステムを作りましょう。
1.Stateの初期化
Stateのプロパティの名前はtextValueで使いましょう。
export default class App extends Component { state = {textValue: ""}; }
2.Stateを読む
表示したいテキストはTextInputが入力されたテキストなので、Stateの値を表示しましょう。
<Text>{this.state.textValue}</Text>
3.Stateをセットする
TextInputのテキストが変わる時にTextを変更したいですが、TextInputはonChangeTextというpropがあります。onChangeTextの値はテキストが変わる時に実行される関数です。関数の引数は変更された後の文字列です。
<TextInput style={styles.input} onChangeText={newValue => this.setState({textValue: newValue})} />
4.サンプルコード
この例のまとめは下記です。
例2:カウントダウン
テキストは一秒に表示している数字を減少するアプリを作ります。100から0までカウントダウンします。
1.Stateの初期化
countは100から始まります。
state = {count: 100}
2.Stateを読む
countの値は<Text>で表示します。
<Text style={styles.text}>{this.state.count}</Text>
3.Stateをセットする
1秒に1ずつ減少したいのでsetInterval()を使います。React NativeでsetIntervalを使う場合はcomponentDidMount()で実行します。componentDidMountはrenderが終わった後で実行される関数です。
componentDidMount(){ setInterval(() => ( this.setState(calculateCount) ), 1000); }
上記の setInterval関数の中で使用するcalculateCountという関数を作ります。下記の関数は前のStateのcountを減少し次のStateをリターン。値は0だったら{count: 0}をリターンします。
function calculateCount(previousState) { let previousCount = previousState.count; let newCount; if(previousCount != 0) { newCount = previousState.count - 1; } else { newCount = 0; } return {count: newCount} }
4.サンプルコード
この例のまとめは下記です。
結論
React Nativeが理解するための大切なポイントはStateだと思います。難しいと思いますが、Stateが分かったら色々な作りたいものを作れると思います。StateのドキュメンテーションはReactJSのドキュメンテーションですが日本語もあるので確認しやすいです。
https://ja.reactjs.org/docs/state-and-lifecycle.html
例をもっと見たかったらじゃんけんゲームの作り方とFormikのパッケージについても見てください。
参考
- 状態
- Stateの初期化
- componentDidMountについて
- renderの再実行
- Stateとlifecycleのドキュメンテーション(日本語)
- React Nativeのドキュメンテーション