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を使用します。これは、次のようにJavaScript内に要素を記述できる構文です:<Text>Hello, I am your cat!</Text>。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パラダイムの中心です。
たとえば、以下のView内にTextとTextInputをネストでき、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>に、Catがレンダリングする異なるnameを渡しています
- TypeScript
- JavaScript
React Nativeのほとんどのコアコンポーネントもpropsでカスタマイズできます。たとえば、Imageを使用する場合、表示する画像を定義するためにsourceというpropを渡します
Imageには、デザインやレイアウトに関連するプロパティと値のペアのJSオブジェクトを受け取るstyleなど、多くの異なるpropsがあります。
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が更新されます。
コンポーネントにstateを追加するには、ReactのuseStateフックを呼び出します。フックは、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プロップを渡します
<Button
onPress={() => {
setIsHungry(false);
}}
//..
/>
これで、誰かがボタンを押すとonPressが発火し、setIsHungry(false)が呼び出されます。これにより、state変数isHungryがfalseに設定されます。isHungryがfalseの場合、Buttonのdisabledプロップは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>の処理を見て、これらのコアコンポーネントのいくつかをさらに深く掘り下げてみましょう。