しばらく使ってないと0ベースで忘れてしますので、触りだけメモ。
環境はMac想定です。すみません。
前提知識
- React NativeはReactを使ってクロスプラットフォーム(iOS, Android)開発を行うためのしくみ
- 開発ツールとしてはexpoか、react-native-cliのいずれかを利用するのが一般的
- expoは簡単だが限られた範囲での開発となる。react-native-cliは制限は無くどんなニーズにも対応
- ただ多くの場合expoの範囲で事足りることが多いのでここではexpoを利用する
- なお、ejectすることでexpoの制限を超えることができる(もちろん失うものもあるが)
環境構築
- node.jsをインストールしておく(必須)
- watchmanをインストールしておく
- yarnをインストールしておく
- XcodeとAndroid Studioもインストールしておいたほうがいい
- Android Studioではエミュレータを作成し、起動できるようにしておく
expoのインストール
npmでglobalにインストールします。
npm install -g expo-cli
作業場+雛形作成
initコマンドでプロジェクトを作成します。
下記の場合、expo_sampleというフォルダが作成され、その中に雛形が生成されます。
expo init expo_sample
いくつか質問をしてきます。
まずは、テンプレートの選択。まあ、blankでよいかと。
? Choose a template: (Use arrow keys)
----- Managed workflow -----
❯ blank minimal dependencies to run and an empty root component
tabs several example screens and tabs using react-navigation
----- Bare workflow -----
bare-minimum minimal setup for using unimodules
次にhome screenに出すapp名を入れろ!と言われるので、まあ、プロジェクトと同じexpo_sampleとでもしておきます。
? Choose a template: expo-template-blank
? Please enter a few initial configuration values.
Read more: https://docs.expo.io/versions/latest/workflow/configuration/ › 50% completed
{
"expo": {
"name": "<The name of your app visible on the home screen>",
"slug": "expo_sample"
}
}
Yarnが見つかればYarnを使うか?と聞かれます。とりあえずYesで。
? Yarn v1.13.0 found. Use Yarn to install dependencies? (Y/n)
ディレクトリ構造
上記の操作が完了すると、下記のような雛形構造が生成されます。
App.jsをいじって開発することになります。
動作確認
何かコーディングする前に、初期状態でうまく動作するか確認しておくといいでしょう。
プロジェクトフォルダにおいて下記コマンドを実行します。
expo start
するとブラウザが起動し、下記の画面が起動します。
この画面を利用して実機によるテスト、エミュレータによるテストが可能です。
実機によるテスト
実機でテストをしたい場合はiOSもしくはAndroidでexpoアプリをインストールして、アプリを利用してQRコードを読み取ることでテストできます。
iOSではカメラでQR読めば「アプリを起動するか?」聞いてきます。
エミュレータによるテスト
上記ブラウザ画面の左メニューで「Run on Android device/emulator」もしくは「Run on iOS simulator」を選びます。ここではiOSシミュレータを利用してみます。
下記のようなものが表示されればOKです。
最低限の実装:Styleをインラインに記述
サンプルコードが長くなるので、外部設定されたSytleをインラインに記述してみます。
import React from 'react';
import { StyleSheet, Text, View } from 'react-native';
export default class App extends React.Component {
render() {
return (
+ <View style={{flex:1, paddingVertical:80, alignItems:'center'}}>
<Text>Open up App.js to start working on your app!</Text>
</View>
);
}
}
-const styles = StyleSheet.create({
- container: {
- flex: 1,
- backgroundColor: '#fff',
- alignItems: 'center',
- justifyContent: 'center',
- },
});
最低限の実装:Buttonを配置。クリックしてアラート表示(ついでにlog出力)
何は無くともボタンは必要。onPressに関数を設定することでその内容が実行されます。
まずはクロージャを利用。
import React from 'react';
+//Buttonを追加
+import { StyleSheet, Text, View, Button } from 'react-native';
export default class App extends React.Component {
render() {
return (
<View style={{flex:1, paddingVertical:80, alignItems:'center'}}>
<Text>Open up App.js to start working on your app!</Text>
+ <Button
+ title="Click Me"
+ onPress={()=>{
+ alert("アラート表示");
+ console.log("コンソールログ")
+ }}
+ />
</View>
);
}
}
実行すると、下記のような感じ。
console.log()はexpo startさせたコンソールに表示されているはずです。
なお、外部関数化することもできます。その場合は、this.functionで呼び出し。
import React from 'react';
//Buttonを追加
import { StyleSheet, Text, View, Button } from 'react-native';
export default class App extends React.Component {
render() {
return (
<View style={{flex:1, paddingVertical:80, alignItems:'center'}}>
<Text>Open up App.js to start working on your app!</Text>
<Button
title="Click Me"
+ onPress={this.showAlert}
/>
</View>
);
}
+ //アラート表示
+ showAlert = () => {
+ alert("アラート表示");
+ console.log("コンソールログ");
+ }
}
最低限の実装:変数(state)の利用
Reactにはstateとpropsという2つの変数を扱う仕組みがあります。まずは、state。
あるリアクトコンポーネント(ここではApp.js)内で利用する変数はすべてstateにおいて定義されている必要があります。
また、変数の更新は
name = "hoge";
というような形はとれず、
this.setState({name: "hoge"});
というような形でsetState()を利用して更新する必要があります。
なお、1つのアプリにApp.js, A.js, B.jsと複数のコンポーネント(画面)が存在する場合、原則としてコンポーネント間で値を共有することができないため、別途Redux等のしくみを利用する必要があります。
以下、サンプルです。
stateにname, ageを表示し、初期値としてhoge, 33を定義しています。
ボタンをクリックしたら、名前がfooに切り替わるというものです。
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
export default class App extends React.Component {
+ //stateを定義
+ state = {
+ name: "hoge",
+ age: 33
+ }
render() {
return (
<View style={{flex:1, paddingVertical:80, alignItems:'center'}}>
+ <Text>こんにちは。{this.state.name}さん。</Text>
<Button
title="Change Name"
+ onPress={this.changeName}
/>
</View>
);
}
+ //name変更
+ changeName = () => {
+ this.setState({
* name: "Foo"
+ });
+ }
}
動作サンプル。
最低限の実装:変数(Props)の利用
propsはタグコンポーネント間で値を受け渡す仕組みです。
コードを見たほうが早いでしょう。という関数によるカスタムタグを定義し、カスタムタグに対しpropsで初期値を渡しています。
import React from 'react';
import { StyleSheet, Text, View, Button } from 'react-native';
export default class App extends React.Component {
//stateを定義
state = {
name: "hoge",
age: 33
}
render() {
return (
<View style={{flex:1, paddingVertical:80, alignItems:'center'}}>
<Text>こんにちは。{this.state.name}さん。</Text>
<Button
title="Change Name"
onPress={this.changeName}
/>
+ <Hello to="Bob"/>
+ <Hello to="Tom"/>
</View>
);
}
//アラート表示
changeName = () => {
this.setState({
name: "Foo"
});
}
}
+function Hello(props){
+ return (
+ <Text>Hello. {props.to}!</Text>
+ );
}
実行サンプル
最低限の処理:Input処理
React(Native)で「え?」と思わされるのがForm等でのInput処理です。
結論から言えば、TextInput等の入力系コンポーネントを配置しただけでは値が変更できません。
下記コードはstateで初期値text1を配置し、それをInputTextの初期値として設定しているコードです。
下記コードを実行して、テキストを編集してみてください。できないはずです。
import React from 'react';
+//TextInputを追加
+import { StyleSheet, Text, View, Button, TextInput } from 'react-native';
export default class App extends React.Component {
//stateを定義
state = {
+ text1 : "placeholder"
}
render() {
return (
<View style={{flex:1, paddingVertical:80, alignItems:'center'}}>
<Text>入力してください</Text>
+ <TextInput
+ value={this.state.text1}
+ />
<Button
title="Entry"
onPress={this.entry}
/>
</View>
);
}
//TextInputの内容をアラートで表示
entry = () => {
alert(this.state.text1);
}
}
実行サンプル
編集可能とするためには、onChangeText()を定義して、テキストが変更される度、stateを更新する処理が必要です。
この辺を簡略化してくれるコンポーネントもありますが、これが基本となります。
import React from 'react';
import { StyleSheet, Text, View, Button, TextInput } from 'react-native';
export default class App extends React.Component {
//stateを定義
state = {
text1 : "placeholder"
}
render() {
return (
<View style={{flex:1, paddingVertical:80, alignItems:'center'}}>
<Text>入力してください</Text>
<TextInput
value={this.state.text1}
+ onChangeText = {(t) => this.setState({text1:t})}
/>
<Button
title="Entry"
onPress={this.entry}
/>
</View>
);
}
//アラート表示
entry = () => {
alert(this.state.text1);
}
}
実行サンプル
最低限の実装:カッコいいコンポーネント(react-native-elements)を使う
npm install react-native-elements
なぜか再度npm installしないと使えません。。。
npm install
yarn add react-native-elementsだと、1回でOKみたい。
そして実装。上と同じ機能をreact-native-elementsのコンポーネントで置き換えてみました。
バージョンアップしてFormInput, FormLabel等はInputに統合されたみたい。。。
import React from 'react';
//Buttonはかぶるの消す
import { StyleSheet, Text, View, TextInput } from 'react-native';
//使うコンポーネントをimport
import { Card, Button, Input} from 'react-native-elements';
export default class App extends React.Component {
//stateを定義
state = {
text1 : "placeholder"
}
render() {
return (
<View style={{flex:1, paddingVertical:80}}>
<Card title="入力してね">
<Input
value={this.state.text1}
label="text1"
errorMessage="error"
onChangeText={(t)=>{this.setState({text1:t})}}
/>
<Button
title="Entry"
buttonStyle={{marginTop:30}}
borderRadius={20}
onPress={this.entry}
/>
</Card>
</View>
);
}
//アラート表示
entry = () => {
alert(this.state.text1);
}
}
実行サンプル
まだいろいろあるけど、必要に応じて随時追加します。