Reactの基礎
React Nativeは、JavaScriptでユーザーインターフェースを構築するための人気のあるオープンソースライブラリであるReact上で動作します。React Nativeを最大限に活用するためには、React自体を理解することが役立ちます。このセクションは、Reactを始めるための入門、または復習コースとして役立ちます。
ここでは、Reactの裏側にあるコアコンセプトについて説明します。
- コンポーネント
- JSX
- props
- state
さらに深く掘り下げたい場合は、Reactの公式ドキュメントを確認することをお勧めします。
最初のコンポーネント
このReact入門の残りの部分では、例として猫を使います。猫は、名前と働くためのカフェが必要な、フレンドリーで親しみやすい生き物です。これがあなたの最初のCatコンポーネントです。
方法は次のとおりです:Cat
コンポーネントを定義するには、まずJavaScriptのimport
を使用してReactとReact NativeのText
コアコンポーネントをインポートします。
import React from 'react';
import {Text} from 'react-native';
あなたのコンポーネントは関数として始まります。
const Cat = () => {};
コンポーネントは設計図のようなものだと考えることができます。関数コンポーネントが返すものはすべて、React要素としてレンダリングされます。React要素を使うと、画面に表示したいものを記述できます。
ここで、Cat
コンポーネントは<Text>
要素をレンダリングします。
const Cat = () => {
return <Text>Hello, I am your cat!</Text>;
};
JavaScriptのexport default
を使用して関数コンポーネントをエクスポートし、アプリ全体で使用できます。
const Cat = () => {
return <Text>Hello, I am your cat!</Text>;
};
export default Cat;
これはコンポーネントをエクスポートする多くの方法のうちの1つです。この種類のエクスポートはSnack Playerでうまく機能します。ただし、アプリのファイル構造によっては、別の規約を使用する必要があるかもしれません。このJavaScriptのインポートとエクスポートに関する便利なチートシートが役立ちます。
それでは、そのreturn
文を詳しく見てみましょう。<Text>Hello, I am your cat!</Text>
は、要素を便利に記述するためのJavaScript構文の一種であるJSXを使用しています。
JSX
ReactとReact NativeはJSXを使用します。これは、<Text>Hello, I am your cat!</Text>
のようにJavaScript内で要素を記述できる構文です。Reactのドキュメントには、JSXに関する包括的なガイドがあり、さらに詳しく学ぶことができます。JSXはJavaScriptなので、その中で変数を使用できます。ここでは、猫の名前name
を宣言し、それを中括弧で<Text>
内に埋め込んでいます。
{getFullName("Rum", "Tum", "Tugger")}
のような関数呼び出しを含め、どんなJavaScript式でも中括弧の間で機能します。
- TypeScript
- JavaScript
中括弧は、JSX内でJSの機能への入り口を作ると考えることができます!
JSXはReactライブラリに含まれているため、ファイルの先頭に
import React from 'react'
がないと動作しません!
カスタムコンポーネント
あなたは既にReact Nativeのコアコンポーネントに出会いました。Reactでは、これらのコンポーネントを互いに入れ子にして新しいコンポーネントを作成できます。これらの入れ子可能で再利用可能なコンポーネントが、Reactパラダイムの中心です。
たとえば、以下のようにText
とTextInput
をView
の中に入れ子にすると、React Nativeはそれらを一緒にレンダリングします。
開発者ノート
- Android
- Web
Web開発に詳しいなら、
<View>
と<Text>
はHTMLを思い起こさせるかもしれません!これらはアプリケーション開発における<div>
と<p>
タグのようなものだと考えることができます。
Androidでは通常、ビューの子要素が画面上でどのように配置されるかを定義するために、ビューを
LinearLayout
、FrameLayout
、RelativeLayout
などの中に入れます。React Nativeでは、View
は子要素のレイアウトにFlexboxを使用します。詳細については、Flexboxによるレイアウトガイドで学ぶことができます。
<Cat>
を使用することで、コードを繰り返すことなく、このコンポーネントを複数回、複数の場所でレンダリングできます。
他のコンポーネントをレンダリングするコンポーネントはすべて親コンポーネントです。ここでは、Cafe
が親コンポーネントであり、各Cat
は子コンポーネントです。
カフェには好きなだけ猫を置くことができます。各<Cat>
は一意の要素をレンダリングし、それをpropsでカスタマイズできます。
Props
Propsは「プロパティ」の略です。Propsを使用すると、Reactコンポーネントをカスタマイズできます。たとえば、ここでは各<Cat>
に異なるname
を渡し、Cat
がそれをレンダリングするようにします。
- TypeScript
- JavaScript
React Nativeのコアコンポーネントのほとんども、propsでカスタマイズできます。たとえば、Image
を使用する場合、表示する画像を定義するためにsource
という名前のpropを渡します。
Image
にはさまざまなpropsがあり、その中にはstyle
も含まれます。これはデザインとレイアウトに関連するプロパティと値のペアからなるJSオブジェクトを受け入れます。
style
の幅と高さを囲む二重の中括弧{{ }}
に注目してください。JSXでは、JavaScriptの値は{}
で参照されます。これは、配列や数値のような文字列以外のものをpropsとして渡す場合に便利です:<Cat food={["fish", "kibble"]} age={2} />
。しかし、JSオブジェクトもまた中括弧で示されます:{width: 200, height: 200}
。したがって、JSXでJSオブジェクトを渡すには、オブジェクトをもう一組の中括弧で囲む必要があります:{{width: 200, height: 200}}
propsとコアコンポーネントのText
、Image
、View
を使って多くのものを作ることができます!しかし、インタラクティブなものを作るには、stateが必要です。
State
propsはコンポーネントがどのようにレンダリングされるかを設定するための引数と考えることができますが、stateはコンポーネントの個人的なデータストレージのようなものです。Stateは、時間とともに変化するデータや、ユーザーのインタラクションから生じるデータを扱うのに便利です。Stateはコンポーネントに記憶を与えます!
一般的なルールとして、コンポーネントがレンダリングされるときの設定にはpropsを使用します。時間とともに変化することが予想されるコンポーネントのデータは、stateを使用して追跡します。
次の例は、2匹の空腹な猫が餌を待っている猫カフェが舞台です。彼らの空腹状態は、(名前とは異なり)時間とともに変化することが予想されるため、stateとして保存されます。猫に餌をやるには、ボタンを押してください。これにより、彼らのstateが更新されます。
ReactのuseState
フックを呼び出すことで、コンポーネントにstateを追加できます。フックとは、Reactの機能に「フックする」ことができる一種の関数です。たとえば、useState
は関数コンポーネントにstateを追加できるフックです。Reactのドキュメントで他の種類のフックについてさらに学ぶことができます。
- TypeScript
- JavaScript
まず、次のようにReactからuseState
をインポートします。
import React, {useState} from 'react';
次に、その関数内でuseState
を呼び出してコンポーネントのstateを宣言します。この例では、useState
はisHungry
というstate変数を作成します。
const Cat = (props: CatProps) => {
const [isHungry, setIsHungry] = useState(true);
// ...
};
useState
を使って、文字列、数値、ブール値、配列、オブジェクトなど、あらゆる種類のデータを追跡できます。たとえば、猫が撫でられた回数をconst [timesPetted, setTimesPetted] = useState(0)
で追跡できます!
useState
を呼び出すと、2つのことが行われます。
- 初期値を持つ「state変数」を作成します。この場合、state変数は
isHungry
で、初期値はtrue
です。 - そのstate変数の値を設定するための関数を作成します—
setIsHungry
です。
どのような名前を使用してもかまいません。しかし、[<getter>, <setter>] = useState(<initialValue>)
というパターンで考えると便利です。
次に、Button
コアコンポーネントを追加し、それにonPress
propを与えます。
<Button
onPress={() => {
setIsHungry(false);
}}
//..
/>
これで、誰かがボタンを押すとonPress
が発火し、setIsHungry(false)
が呼び出されます。これにより、state変数isHungry
がfalse
に設定されます。isHungry
がfalseの場合、Button
のdisabled
propはtrue
に設定され、そのtitle
も変わります。
<Button
//..
disabled={!isHungry}
title={isHungry ? 'Give me some food, please!' : 'Thank you!'}
/>
isHungry
はconstであるにもかかわらず、再代入可能に見えることに気づいたかもしれません!何が起こっているかというと、setIsHungry
のようなstate設定関数が呼ばれると、そのコンポーネントは再レンダリングされます。この場合、Cat
関数が再度実行され、今回はuseState
がisHungry
の次の値を返します。
最後に、猫たちをCafe
コンポーネントの中に入れます。
const Cafe = () => {
return (
<>
<Cat name="Munkustrap" />
<Cat name="Spot" />
</>
);
};
上記の
<>
と</>
が見えますか?これらのJSXの一部はフラグメントです。隣接するJSX要素は、囲むタグでラップする必要があります。フラグメントを使用すると、View
のような余分で不要なラップ要素をネストすることなく、それを行うことができます。
ReactとReact Nativeのコアコンポーネントの両方をカバーしたので、次は<TextInput>
の扱い方を見て、これらのコアコンポーネントのいくつかをより深く掘り下げてみましょう。