はじめに
普段はAngularなどでWebアプリケーションを開発している私ですが、急にReact Nativeを学びたくなったので、徒然とこの記事を書きはじめました。
↓な感じのToDoリストを作ります。
最終成果物はこちらです。
todo-sample
この記事でわかること
- React Nativeの基礎の基礎
ベストプラクティス的なやつとか、こんな応用的な使い方してやったぜ!みたいなのは全く書いてません。
まずはインストールしないとはじまらない
React Nativeには「node」と「watchman」が必要らしいので、さくっとインストールします。
brew install node
brew install watchman
続いて、React Nativeの本体をインストールです。
npm install -g react-native-cli
プロジェクトを作って起動してみる
react-native init Todo
cd Todo
react-native run-ios
この画面が表示されれば起動成功です。
ちなみにシミュレーター上で「Command + D → Debug JS Remotely」を選択することで、デベロッパーツールによるデバッグできるので、覚えておいたほうが良いです。
簡単に設計する
この後は「index.ios.js」に処理をズンズン書いていけば何とかなりそうですが、せっかくなので手を動かす前に必要なClassはどんな感じになるか考えてみます。
- TodoListContainer
画面を囲うContainer。TodoListとFooterを持つ。 - TodoList
TodoList全体。TodoListItemを持つ。 - TodoListItem
TodoList単体。CheckboxとTodoを表示するTextを持つ。 - Footer
画面下部に固定されているFooter。textInputと追加ボタンを持つ。
最低これらのClassがあれば何とかなりそうです。
初期データを表示する
まずは「index.ios.js」をいじくって、TodoListContainerを初期化します。
- index.ios.js
import React, { Component } from 'react';
import {
AppRegistry
} from 'react-native';
import TodoListContainer from 'Todo/src/TodoListContainer';
class Todo extends Component {
constructor(props) {
super(props);
}
render() {
return (
<TodoListContainer />
);
}
}
AppRegistry.registerComponent('Todo', () => Todo);
データは、Todoを追加する処理をする「Footer」とTodoを描画する「TodoList」の橋渡し的な役割を担う「TodoListConainer」に持たせます。
- TodoListContainer.js
this.state = {
todos: [
{text: 'Learn react native'},
{text: 'Make a to-do app'}
]
}
そして、「TodoList」のpropsにデータを渡します。
stateとpropsは下記が参考になります。
React における State と Props の違い
render() {
return (
<View style={{flex: 1}}>
<ScrollView
style={styles.base}
>
<TodoList
todos={this.state.todos} //TodoListのpropsにデータを渡す
/>
</ScrollView>
・・・
}
続いて、ReactNativeで用意されているコンポーネントである「ListView」でTodoを描画します。
- TodoList.js
constructor(props) {
super(props);
//ListViewで扱うデータ形式にする
this.dataSource = new ListView.DataSource({
rowHasChanged: (row1, row2) => row1 !== row2
});
}
render() {
return (
<ListView
dataSource={this.dataSource.cloneWithRows(this.props.todos)}
renderRow={(todo) => <TodoListItem {...todo} />}
renderSeparator={this.renderSeparator}
/>
);
}
- TodoListItem.js
render() {
return (
<View style={styles.todo}>
<CheckBox
isChecked={this.props.complete}
onClick={()=>this.onClick()}
/>
<Text style={[styles.text, this.state.isChecked ? styles.isTextDisabled : null]}>
{this.props.text}
</Text>
</View>
);
}
Checkboxは下記コンポーネントを使わせていただきました。
react-native-check-box
Todoを追加する
Todoの追加は「Footer」に配置してある「追加」が押されたタイミングで、「TodoListContainer」のstateを更新して行います。
- Footer.js
onAddPress() {
// TodoListContainerのaddTodoメソッドにtextを渡して実行
this.props.addTodo(this.state.text);
// Todo追加後はTextInputを空にする
this.setState({
text: ''
});
}
- TodoListContainer.js
stateにセットした配列に新しく値を追加する際は、concatで処理するのが定石っぽいのでそうします。
addTodo(text) {
this.setState({
todos: this.state.todos.concat([{text: text}])
});
}
追加された!∩( ・ω・)∩ばんじゃーい
おわりに
そんなこんなでToDoリスト(ToDoの削除ができないのは気にしない)が出来上がりました。
React.jsをある程度知っていれば思った以上に高速で開発できますね…
やっててよかったReact.js。