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>こんにちは、あなたの猫です!</Text>
は、要素の記述を便利にするJavaScript構文の一種であるJSXを使用しています。
JSX
ReactとReact Nativeは、JavaScript内で<Text>こんにちは、あなたの猫です!</Text>
のように要素を記述できる構文であるJSXを使用します。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は「properties」の略です。Propsを使用すると、Reactコンポーネントをカスタマイズできます。たとえば、ここでは、各<Cat>
に、Cat
がレンダリングする別のname
を渡します。
- TypeScript
- JavaScript
React Nativeのコアコンポーネントのほとんども、propsでカスタマイズできます。たとえば、Image
を使用する場合は、表示する画像を定義するためにsource
という名前のpropsを渡します。
Image
には、デザインとレイアウトに関連するプロパティと値のペアのJSオブジェクトを受け入れるstyle
など、さまざまなpropsがあります。
style
の幅と高さを囲む二重波括弧{{ }}
に注意してください。JSXでは、JavaScriptの値は{}
で参照されます。これは、<Cat food={["fish", "kibble"]} age={2} />
のように、propsとして文字列以外のもの(配列や数値など)を渡す場合に便利です。ただし、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
propsを与えます。
<Button
onPress={() => {
setIsHungry(false);
}}
//..
/>
これで、誰かがボタンを押すと、onPress
が発火し、setIsHungry(false)
が呼び出されます。これにより、state変数isHungry
がfalse
に設定されます。isHungry
がfalseの場合、Button
のdisabled
propsは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>
の処理を見て、これらのコアコンポーネントのいくつかについて詳しく見ていきましょう。