メインコンテンツへスキップ

Reactの基礎

React Nativeは、JavaScriptでユーザーインターフェースを構築するための人気のあるオープンソースライブラリであるReact上で動作します。React Nativeを最大限に活用するためには、React自体を理解することが役立ちます。このセクションは、Reactを始めるための入門、または復習コースとして役立ちます。

ここでは、Reactの裏側にあるコアコンセプトについて説明します。

  • コンポーネント
  • JSX
  • props
  • state

さらに深く掘り下げたい場合は、Reactの公式ドキュメントを確認することをお勧めします。

最初のコンポーネント

このReact入門の残りの部分では、例として猫を使います。猫は、名前と働くためのカフェが必要な、フレンドリーで親しみやすい生き物です。これがあなたの最初のCatコンポーネントです。

方法は次のとおりです:Catコンポーネントを定義するには、まずJavaScriptのimportを使用してReactとReact NativeのTextコアコンポーネントをインポートします。

tsx
import React from 'react';
import {Text} from 'react-native';

あなたのコンポーネントは関数として始まります。

tsx
const Cat = () => {};

コンポーネントは設計図のようなものだと考えることができます。関数コンポーネントが返すものはすべて、React要素としてレンダリングされます。React要素を使うと、画面に表示したいものを記述できます。

ここで、Catコンポーネントは<Text>要素をレンダリングします。

tsx
const Cat = () => {
return <Text>Hello, I am your cat!</Text>;
};

JavaScriptのexport defaultを使用して関数コンポーネントをエクスポートし、アプリ全体で使用できます。

tsx
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式でも中括弧の間で機能します。

中括弧は、JSX内でJSの機能への入り口を作ると考えることができます!

JSXはReactライブラリに含まれているため、ファイルの先頭にimport React from 'react'がないと動作しません!

カスタムコンポーネント

あなたは既にReact Nativeのコアコンポーネントに出会いました。Reactでは、これらのコンポーネントを互いに入れ子にして新しいコンポーネントを作成できます。これらの入れ子可能で再利用可能なコンポーネントが、Reactパラダイムの中心です。

たとえば、以下のようにTextTextInputViewの中に入れ子にすると、React Nativeはそれらを一緒にレンダリングします。

開発者ノート

Web開発に詳しいなら、<View><Text>はHTMLを思い起こさせるかもしれません!これらはアプリケーション開発における<div><p>タグのようなものだと考えることができます。

<Cat>を使用することで、コードを繰り返すことなく、このコンポーネントを複数回、複数の場所でレンダリングできます。

他のコンポーネントをレンダリングするコンポーネントはすべて親コンポーネントです。ここでは、Cafeが親コンポーネントであり、各Cat子コンポーネントです。

カフェには好きなだけ猫を置くことができます。各<Cat>は一意の要素をレンダリングし、それをpropsでカスタマイズできます。

Props

Propsは「プロパティ」の略です。Propsを使用すると、Reactコンポーネントをカスタマイズできます。たとえば、ここでは各<Cat>に異なるnameを渡し、Catがそれをレンダリングするようにします。

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とコアコンポーネントのTextImageViewを使って多くのものを作ることができます!しかし、インタラクティブなものを作るには、stateが必要です。

State

propsはコンポーネントがどのようにレンダリングされるかを設定するための引数と考えることができますが、stateはコンポーネントの個人的なデータストレージのようなものです。Stateは、時間とともに変化するデータや、ユーザーのインタラクションから生じるデータを扱うのに便利です。Stateはコンポーネントに記憶を与えます!

一般的なルールとして、コンポーネントがレンダリングされるときの設定にはpropsを使用します。時間とともに変化することが予想されるコンポーネントのデータは、stateを使用して追跡します。

次の例は、2匹の空腹な猫が餌を待っている猫カフェが舞台です。彼らの空腹状態は、(名前とは異なり)時間とともに変化することが予想されるため、stateとして保存されます。猫に餌をやるには、ボタンを押してください。これにより、彼らのstateが更新されます。

ReactのuseStateフックを呼び出すことで、コンポーネントにstateを追加できます。フックとは、Reactの機能に「フックする」ことができる一種の関数です。たとえば、useStateは関数コンポーネントにstateを追加できるフックです。Reactのドキュメントで他の種類のフックについてさらに学ぶことができます。

まず、次のようにReactからuseStateをインポートします。

tsx
import React, {useState} from 'react';

次に、その関数内でuseStateを呼び出してコンポーネントのstateを宣言します。この例では、useStateisHungryというstate変数を作成します。

tsx
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を与えます。

tsx
<Button
onPress={() => {
setIsHungry(false);
}}
//..
/>

これで、誰かがボタンを押すとonPressが発火し、setIsHungry(false)が呼び出されます。これにより、state変数isHungryfalseに設定されます。isHungryがfalseの場合、Buttondisabled propはtrueに設定され、そのtitleも変わります。

tsx
<Button
//..
disabled={!isHungry}
title={isHungry ? 'Give me some food, please!' : 'Thank you!'}
/>

isHungryconstであるにもかかわらず、再代入可能に見えることに気づいたかもしれません!何が起こっているかというと、setIsHungryのようなstate設定関数が呼ばれると、そのコンポーネントは再レンダリングされます。この場合、Cat関数が再度実行され、今回はuseStateisHungryの次の値を返します。

最後に、猫たちをCafeコンポーネントの中に入れます。

tsx
const Cafe = () => {
return (
<>
<Cat name="Munkustrap" />
<Cat name="Spot" />
</>
);
};

上記の<></>が見えますか?これらのJSXの一部はフラグメントです。隣接するJSX要素は、囲むタグでラップする必要があります。フラグメントを使用すると、Viewのような余分で不要なラップ要素をネストすることなく、それを行うことができます。


ReactとReact Nativeのコアコンポーネントの両方をカバーしたので、次は<TextInput>の扱い方を見て、これらのコアコンポーネントのいくつかをより深く掘り下げてみましょう。