UIの説明
Reactは、ユーザーインターフェース(UI)をレンダリングするためのJavaScriptライブラリです。UIは、ボタン、テキスト、画像などの小さな単位から構築されます。Reactを使用すると、それらを再利用可能で入れ子可能なコンポーネントに組み合わせることができます。ウェブサイトから電話アプリまで、画面上のすべてのものはコンポーネントに分解できます。この章では、Reactコンポーネントの作成、カスタマイズ、条件付き表示について学習します。
この章の内容
最初のコンポーネント
Reactアプリケーションは、コンポーネントと呼ばれるUIの分離された部分から構築されています。Reactコンポーネントは、マークアップを散りばめることができるJavaScript関数です。コンポーネントは、ボタンのように小さいものから、ページ全体のように大きいものまで、さまざまです。ここに、3つのProfile
コンポーネントをレンダリングするGallery
コンポーネントがあります。
function Profile() { return ( <img src="https://i.imgur.com/MK3eW3As.jpg" alt="Katherine Johnson" /> ); } export default function Gallery() { return ( <section> <h1>Amazing scientists</h1> <Profile /> <Profile /> <Profile /> </section> ); }
コンポーネントのインポートとエクスポート
1つのファイルに多くのコンポーネントを宣言できますが、ファイルが大きくなるとナビゲーションが難しくなります。これを解決するために、コンポーネントを独自のファイルにエクスポートし、別のファイルからそのコンポーネントをインポートすることができます。
import Profile from './Profile.js'; export default function Gallery() { return ( <section> <h1>Amazing scientists</h1> <Profile /> <Profile /> <Profile /> </section> ); }
JSXによるマークアップの記述
各Reactコンポーネントは、Reactがブラウザにレンダリングするマークアップを含むことができるJavaScript関数です。Reactコンポーネントは、そのマークアップを表すためにJSXと呼ばれる構文拡張を使用します。JSXはHTMLによく似ていますが、少し厳格で、動的な情報を表示できます。
既存のHTMLマークアップをReactコンポーネントに貼り付けると、必ずしも動作するとは限りません。
export default function TodoList() { return ( // This doesn't quite work! <h1>Hedy Lamarr's Todos</h1> <img src="https://i.imgur.com/yXOvdOSs.jpg" alt="Hedy Lamarr" class="photo" > <ul> <li>Invent new traffic lights <li>Rehearse a movie scene <li>Improve spectrum technology </ul>
このような既存のHTMLがある場合は、コンバーターを使用して修正できます。
export default function TodoList() { return ( <> <h1>Hedy Lamarr's Todos</h1> <img src="https://i.imgur.com/yXOvdOSs.jpg" alt="Hedy Lamarr" className="photo" /> <ul> <li>Invent new traffic lights</li> <li>Rehearse a movie scene</li> <li>Improve spectrum technology</li> </ul> </> ); }
中括弧を使ったJSXにおけるJavaScript
JSXを使うと、JavaScriptファイルの中にHTMLのようなマークアップを記述でき、レンダリングロジックとコンテンツを同じ場所に保持できます。マークアップ内にちょっとしたJavaScriptロジックを追加したり、動的なプロパティを参照したい場合もあります。そのような場合は、JSX内で波括弧を使ってJavaScriptへの「窓を開ける」ことができます。
const person = { name: 'Gregorio Y. Zara', theme: { backgroundColor: 'black', color: 'pink' } }; export default function TodoList() { return ( <div style={person.theme}> <h1>{person.name}'s Todos</h1> <img className="avatar" src="https://i.imgur.com/7vQD0fPs.jpg" alt="Gregorio Y. Zara" /> <ul> <li>Improve the videophone</li> <li>Prepare aeronautics lectures</li> <li>Work on the alcohol-fuelled engine</li> </ul> </div> ); }
コンポーネントへのpropsの受け渡し
Reactコンポーネントは、互いに通信するためにpropsを使用します。すべての親コンポーネントは、子コンポーネントにpropsを与えることで、いくつかの情報を渡すことができます。propsはHTML属性を思い起こさせるかもしれませんが、オブジェクト、配列、関数、さらにはJSXを含む、あらゆるJavaScript値を渡すことができます!
import { getImageUrl } from './utils.js' export default function Profile() { return ( <Card> <Avatar size={100} person={{ name: 'Katsuko Saruhashi', imageId: 'YfeOqp2' }} /> </Card> ); } function Avatar({ person, size }) { return ( <img className="avatar" src={getImageUrl(person)} alt={person.name} width={size} height={size} /> ); } function Card({ children }) { return ( <div className="card"> {children} </div> ); }
条件付きレンダリング
コンポーネントは、多くの場合、さまざまな条件に応じて異なるものを表示する必要があります。Reactでは、if
文、&&
、? :
演算子などのJavaScript構文を使用して、JSXを条件付きでレンダリングできます。
この例では、JavaScriptの&&
演算子を使用して、チェックマークを条件付きでレンダリングしています。
function Item({ name, isPacked }) { return ( <li className="item"> {name} {isPacked && '✅'} </li> ); } export default function PackingList() { return ( <section> <h1>Sally Ride's Packing List</h1> <ul> <Item isPacked={true} name="Space suit" /> <Item isPacked={true} name="Helmet with a golden leaf" /> <Item isPacked={false} name="Photo of Tam" /> </ul> </section> ); }
リストのレンダリング
データの集合から、複数の類似したコンポーネントを表示したいことがよくあります。Reactでは、JavaScriptのfilter()
とmap()
を使用して、データの配列をコンポーネントの配列にフィルタリングおよび変換できます。
各配列項目に対して、key
を指定する必要があります。通常、データベースのIDをkey
として使用します。キーにより、リストが変更された場合でも、Reactは各項目のリスト内での位置を追跡できます。
import { people } from './data.js'; import { getImageUrl } from './utils.js'; export default function List() { const listItems = people.map(person => <li key={person.id}> <img src={getImageUrl(person)} alt={person.name} /> <p> <b>{person.name}:</b> {' ' + person.profession + ' '} known for {person.accomplishment} </p> </li> ); return ( <article> <h1>Scientists</h1> <ul>{listItems}</ul> </article> ); }
コンポーネントをピュアに保つ
いくつかのJavaScript関数はピュアです。ピュア関数とは
- 自分の仕事だけに専念する関数です。呼び出される前に存在していたオブジェクトや変数を変更しません。
- 同じ入力、同じ出力。同じ入力が与えられた場合、ピュア関数は常に同じ結果を返す必要があります。
コンポーネントをピュア関数としてのみ厳密に記述することで、コードベースの規模が大きくなっても、不可解なバグや予測できない動作という問題全体を回避できます。不純なコンポーネントの例を以下に示します。
let guest = 0; function Cup() { // Bad: changing a preexisting variable! guest = guest + 1; return <h2>Tea cup for guest #{guest}</h2>; } export default function TeaSet() { return ( <> <Cup /> <Cup /> <Cup /> </> ); }
既存の変数を変更する代わりにpropを渡すことで、このコンポーネントをピュアにすることができます。
function Cup({ guest }) { return <h2>Tea cup for guest #{guest}</h2>; } export default function TeaSet() { return ( <> <Cup guest={1} /> <Cup guest={2} /> <Cup guest={3} /> </> ); }
ツリーとしてのUI
Reactは、コンポーネントとモジュール間の関係をモデル化するためにツリーを使用します。
Reactレンダーツリーは、コンポーネント間の親子関係を表したものです。


Reactレンダーツリーの例。
ツリーの上部、ルートコンポーネントに近いコンポーネントは、トップレベルコンポーネントと見なされます。子コンポーネントを持たないコンポーネントは、リーフコンポーネントです。このコンポーネントの分類は、データフローとレンダリングのパフォーマンスを理解するのに役立ちます。
JavaScriptモジュール間の関係をモデル化することは、アプリケーションを理解するもう1つの有用な方法です。これをモジュール依存関係ツリーと呼びます。


モジュール依存関係ツリーの例。
依存関係ツリーは、多くの場合、ビルドツールによって使用され、クライアントがダウンロードしてレンダリングするために必要なすべてのJavaScriptコードをバンドルします。バンドルサイズが大きいと、Reactアプリケーションのユーザーエクスペリエンスが悪化します。このような問題をデバッグするには、モジュール依存関係ツリーを理解することが役立ちます。
次のステップ
最初のコンポーネント に進んで、この章をページごとに読んでいきましょう!
あるいは、これらのトピックに既に精通している場合は、インタラクティビティの追加について読んでみませんか?