はじめに
今年から仕事でReact Native
でのアプリ開発をすることになったので、React Nativeについて勉強開始。まず簡単に重要な部分のみ備忘録でまとめておく。
公式ドキュメントがあるのでこちらを読みながら進めていく。
https://reactnative.dev/docs/getting-started
React Nativeとは
React Nativeは、JavaScript(もしくはTypeScript)でモバイルアプリを開発できるフレームワーク。1つのコードベースでiOSとAndroidの両方に対応するアプリを開発可能(クロスプラットフォーム開発)
- API通信やアプリのロジックはJavaScriptで記述する。
- UIの見た目や振る舞いは、React Nativeコンポーネントを使って記述する。Reactは、ユーザーインターフェース(UI)を構築するためのJavaScriptライブラリであり(プログラミング言語ではない)、主にコンポーネントベースでUIを作成する。
React Nativeコンポーネントとは?
Reactは、JavaScriptを拡張する形でUIコンポーネントを定義する仕組みを提供する。Reactでは、コンポーネントがUI構築の基本単位。React Nativeが提供するコンポーネントは、Reactコンポーネントの一種だが、厳密には「React Native専用のネイティブコンポーネント」
実際のコードはJavaScriptで記述されるが、JSXという構文を使うことで、HTMLのようなUI構造を記述できる。
Reactコンポーネント
- Webブラウザ向けに作られたUI部品。
- HTMLのタグ(例:
<div>
,<span>
,<button>
)を使って構成される。 - React DOM(Web用のレンダラー)がHTML要素を生成する。
React Nativeコンポーネント
- モバイルアプリ向けに作られたUI部品。
- HTMLタグではなく、ネイティブのUI要素(iOSやAndroidのビュー)を使う。
- React Nativeが提供するコンポーネント(例:
<View>
,<Text>
,<Image>
)が、iOSならUIView
、AndroidならView
のようなネイティブのUI要素に変換される。<View>はHTMLの<Div>, <Text>はHTMLの<p>に相当すると考えれば良い。
React Nativeコンポーネントは、Reactコンポーネントの「兄弟」とも言える存在だが、使用する環境(Webではなくアプリ)と動作(ネイティブのUI要素に変換される)が異なる。
import React from 'react';
import { View, Text, Button } from 'react-native';
const App = () => {
const handlePress = () => {
fetch('https://api.example.com/data') // API通信はJavaScript
.then(response => response.json())
.then(data => console.log(data));
};
return (
<View>
<Text>Hello, React Native!</Text> {/* UIはReactコンポーネント */}
<Button title="Fetch Data" onPress={handlePress} />
</View>
);
};
上記例では、
fetch
を使ったAPI通信はJavaScriptの標準機能。View
やText
はReact Nativeが提供するコンポーネントで、UIを構築している。
コンポーネントは再利用可能で、他のコンポーネントと組み合わせて複雑なUIを構築できる。関数コンポーネントとして定義することが一般的。
import React from 'react';
import { Text } from 'react-native';
const Cat = () => {
return <Text>Hello, I am your cat!</Text>;
};
export default Cat;
上記の例では、Cat
という関数コンポーネントが<Text>
要素を返している。
JSX(JavaScript XML)
JSXは、JavaScriptでUIコンポーネントを記述する構文(JavaScriptの拡張構文)であり、XMLやHTMLに似た記述が可能。 開発者がJSXで記述すると、トランスパイラ(Babel)がJSXを通常のJavaScriptに変換し、変換されたJavaScriptがブラウザで動作し、ReactがUIを生成するという流れ。
従来のReactは、React.createElement()
を使ってUIを構築していたが、これではコードが長くなり、理解しづらいために、UI構築を直感的でわかりやすくするために導入された。
例:JSXなし(従来の方法)
const element = React.createElement('div', { className: 'container' },
React.createElement('h1', null, 'Hello, world!'),
React.createElement('p', null, 'Welcome to React')
);
JSXを使った記述
const element = (
<div className="container">
<h1>Hello, world!</h1>
<p>Welcome to React</p>
</div>
);
JSX内で変数や関数の結果を埋め込む際には、波括弧 {}
を使用する。下記例では、name
変数の値が<Text>
要素内に埋め込まれる。
const name = 'Whiskers';
const Cat = () => {
return <Text>Hello, I am {name}!</Text>;
};
Props(プロパティ)
Propsは、propertyの略で、関数の引数と同じような役割を果たす。ただし、Reactコンポーネントに特化した概念であり、コンポーネントに外部から値を渡して動作をカスタマイズするための手段。
関数の引数と異なる点は
- Propsはオブジェクト形式で渡され、複数の値をまとめて扱えるため、関数の引数のようにプロパティごとに多くの引数を用意する必要があない。
- 読み取り専用であり、親コンポーネントから渡された値を子コンポーネントで変更することはできない。親の状態を変更したい場合は、コールバック関数を使って親のデータを更新する
親コンポーネントから子コンポーネントに値を渡すことで、動的なUIを構築できる。Cafe
コンポーネントは、Cat
コンポーネントにname
というプロパティを渡している。
const Cat = (props) => {
return <Text>Hello, I am {props.name}!</Text>;
};
const Cafe = () => {
return (
<>
<Cat name="Whiskers" />
<Cat name="Fluffy" />
</>
);
};
State(状態)
Stateは、コンポーネント内で変更可能なデータを管理するための仕組み。ユーザーの操作やイベントに応じて状態を更新し、それに基づいてUIを再レンダリングする。
Reactでは、useState
フックを使ってStateを管理する。
useState
の基本的な使い方
const [count, setCount] = useState(0);
useState(0)
の0
が初期値count
は現在の状態を保持する変数setCount
はcount
を更新するための関数
useStateが返すのは常に2つ(現在の状態を保持する変数・状態を更新する関数)のみであり、配列の要素が3つや4つになることはない。
import React, { useState } from 'react';
import { Text, Button, View } from 'react-native';
const Cat = () => {
const [isHungry, setIsHungry] = useState(true);
return (
<View>
<Text>
I am {isHungry ? 'hungry' : 'full'}!
</Text>
<Button
onPress={() => {
setIsHungry(false);
}}
title="Feed me"
/>
</View>
);
};