第2回 コンポーネントのインポートとエクスポート、レンダー
前回は、Border7アプリケーションとプログラムの概要についてお話ししました。
今回から、いよいよ実際にBorder7アプリケーションの開発をしていきます。
今回学ぶこと
今回はAppコンポーネントの実装を通して以下の内容を学びます。
- コンポーネントのインポートとエクスポート
- コンポーネントのレンダー
まずはそれぞれの技術について学びましょう。
スキップして実装に進む場合はこちら。
コンポーネントのインポートとエクスポート
Reactには、あるファイルで作成したコンポーネントを別のファイルで使えるようにする仕組みがあります。
その仕組みがインポートとエクスポートです1。
あるファイルで作成したコンポーネントはエクスポートをすることで別のファイルでインポートして使えるようになります。
コンポーネントをインポート・エクスポートするには以下の2つの方法があります。
- 名前付きインポート、名前付きエクスポート
- デフォルトインポート、デフォルトエクスポート
名前付きインポート、名前付きエクスポート
名前付きインポート、名前付きエクスポートはその名のとおり、コンポーネントを名前付きでインポート・エクスポートします。
コンポーネントを名前付きインポートするためには、そのコンポーネントは名前付きエクスポートされていなければなりません。対象のコンポーネントが名前付きエクスポートされているかどうかは、その関数コンポーネントの宣言を見ることで確認ができます。
以下は名前付きエクスポートのサンプルコードです。
export function MyComponentA() {
return (
<>MyComponentAを名前付きエクスポート</>
)
}
このように、関数宣言の前に export キーワードを付けることで名前付きエクスポートとなります。
名前付きエクスポートされたコンポーネントは、そのコンポーネント名(関数コンポーネントの場合はその関数名)を指定することでインポートができます。
名前付きインポートは以下の文法で記述します。
import { コンポーネント名 } from '[エクスポートされたファイルのパス]'
以下は名前付きインポートのサンプルコードです。
MyComponentBは、MyComponentAと同じディレクトリにあるファイルとします。
import { MyComponentA } from './MyComponentA'
export function MyComponentB() {
return (
<MyComponentA/>
)
}
デフォルトインポート、デフォルトエクスポート
次はデフォルトインポート、デフォルトエクスポートについてです。
名前付きインポート、名前付きエクスポートとの違いを意識すると理解しやすいです。
インポートとエクスポート、一つずつ見ていきましょう。
名前付きインポートが名前を指定してコンポーネントをインポートしていたのに対し、デフォルトインポートは名前を指定しません。
あるファイルの既定(デフォルト)のコンポーネントを任意の名前でインポートします。
デフォルトエクスポートは、デフォルトインポートされる既定のコンポーネントを指定します。
一つのファイルにつき一つ指定することが可能です。
export default function MyComponentA() {
return (
<>MyComponentAをデフォルトエクスポート</>
)
}
デフォルトインポートは以下の文法で記述します。
import コンポーネント名 from '[エクスポートされたファイルのパス]'
名前付きインポートが { コンポーネント名 } と { } で括っていたのに対し、デフォルトコンポーネントは { } で括りません。
コンポーネント名 の部分も、対象のコンポーネント名(関数名)と合わせる必要もありません。
以下はデフォルトインポートのサンプルコードです。
MyComponentAを任意の名前でインポートしていることに注目してください。
import DefaultImportedComponent from './MyComponentA'
export function MyComponentB() {
return (
<DefaultImportedComponent/>
)
}
コンポーネントのレンダー
Reactにおける「レンダー」とは
Reactでは「レンダー」という言葉がよく使われます。
「レンダリング」と表現されることもありますが、同じものと考えて差し支えありません。
ただし、使われている文脈がフロントエンド全般のものなのか、Reactのものなのかで、その意味は異なるので注意が必要です。
フロントエンド全般の文脈におけるレンダリングとは「ブラウザレンダリング」のことを指し、ブラウザが画面を描画することを意味します。
Reactの文脈におけるレンダーとは、ブラウザレンダリングの前にReactが行う処理のうちの一つで、画面に表示する情報を得るための計算を意味します。
レンダーが実際に何を行っているのかについてはReactの公式ドキュメントで解説されています。
ここでは以下の文章を引用するに留め、詳細な解説についてはReactの公式ドキュメントに譲ります。
“Rendering” is React calling your components.
「レンダー」とは、React がコンポーネントを呼び出すことです。
https://react.dev/learn/render-and-commit
さて、上記では「レンダー」と「レンダリング」の使い分けで、少しややこしい書き方をしてしまいました。
というのも、フロントエンド全般では「レンダリング」を用いるのが一般的ですが、Reactの文脈では「レンダー」を用いるほうが望ましいと筆者は考えているためです2。
プロプラ!では、Reactの公式ドキュメントにあわせて「レンダー」を使用します。
プロプラ!でのレンダーの使い方
前項では、Reactにおける「レンダー」の定義について確認しました。
しかしながら、この「レンダー」という言葉は使われ方がまちまちで、React公式ドキュメントの「条件付きレンダー」などのページでは「画面に表示する」とも取れる使われ方がされていると筆者は感じています。
これは「
https://ja.react.dev/learn/conditional-rendering#conditional-ternary-operator–isPacked
が true ならname + ' ✔'
をレンダーし、それ以外 (:
) の場合はname
をレンダーする」というように読んでください。
ここではその是非を論じるつもりはなく、むしろそういった意味で使ったほうが都合が良いときもあると筆者は考えています。
Reactが定義している「レンダー」の本来の意味に従おうとすると、以下のようになんとも回りくどい表現になってしまいます。
これは「
Reactの公式ドキュメントの「条件付きレンダー」より。レンダーを本来の意味に従ってみた。isPacked
が true ならname + ' ✔'
をレンダーして返されるJSX内に含め、それ以外 (:
) の場合はname
をレンダーして返されるJSX内に含める」というように読んでください。
プロプラ!においても、本来の意味に従うことよりもわかりやすさを重視して、「レンダー」という言葉を上記のReact公式ドキュメントと同じような使い方をしています。
Reactにおける「レンダー」は「ブラウザレンダリング」とは違うという前提のもと、「レンダー」は「Reactがコンポーネントを画面に描画するための処理なんだな」だとか「コンポーネントを画面に描画するための処理なんだな」と理解しておけば十分でしょう。
実装
ここまでで、コンポーネントのインポートとエクスポート、レンダーについて学びました。
必要な知識が揃いましたので、早速実装に入りましょう。
App.jsx の実装
src/App.jsx を開いてください。
AppコンポーネントはBorder7アプリケーションをレンダーする大本のコンポーネントです。
Appコンポーネントを実装することで、画面にBorder7アプリケーションが表示されるようになります。
Appコンポーネントには以下のJsDocを記載しています。
これがAppコンポーネントの設計書です。
/**
* App Component
* 1. src/components/Title.jsx から Title コンポーネントをインポートする
* 2. src/Border7.jsx から Border7 コンポーネントをインポートする
* 3. JSX内のコメントで示している箇所に Title コンポーネント, Border7 コンポーネントをレンダーする
*
* @returns {JSX.Element} App
*/
export default function App() {
プロプラ!では、このようにJsDocに設計書を記載しています。
コンポーネントのインポートとエクスポート
設計書の 1. と 2. を見てみましょう。
1. src/components/Title.jsx から Title コンポーネントをインポートする
2. src/Border7.jsx から Border7 コンポーネントをインポートする
それぞれ Title コンポーネント と Border7 コンポーネント をインポートするよう指示されています。
これら二つのコンポーネントはすでにエクスポートされています。
それぞれのコンポーネントの宣言を見てみましょう。
export default function Title() {
return (
<>
<Typography variant="h1">{/* Box1 */}</Typography>
<Typography variant="h2">{/* Box2 */}</Typography>
</>
)
}
export default function Border7() {
return (
<Container>
<PlayArea>
{/* CardBox */}
{/* MessageBox1 */}
{/* Controller */}
{/* MessageBox2 */}
</PlayArea>
{/* ScoreBoard */}
</Container>
)
}
export default でエクスポートされているのでデフォルトエクスポートになります。
設計書の指示に従って、Title コンポーネント と Border7 コンポーネント をインポートしてください。
コンポーネントのレンダー
続いて、設計書の 3. を見てみましょう。
3. JSX内のコメントで示している箇所に Title コンポーネント, Border7 コンポーネントをレンダーする
ここまでの手順でインポートした Title コンポーネント と Border7 コンポーネント をレンダーするよう指示されています。
設計書の指示に従って、JSX内のコメントで示している箇所に Title コンポーネント と Border7 コンポーネント をレンダーしてください。
実装後の画面イメージ
以上で今回の実装はすべて完了です。
問題なく実装できていれば、以下のような画面が表示されていると思います。
まとめ
今回はコンポーネントのインポートとエクスポート、レンダーについて学びました。
インポートとエクスポート
- export キーワードで名前付きエクスポート
- 名前付きエクスポートされたコンポーネントは、{ } で括る名前付きインポート
- export default キーワードでデフォルトエクスポート
- デフォルトエクスポートされたコンポーネントは、{ } で括らない名前付きインポート
レンダー
- レンダー(レンダリング)はその文脈によって意味が異なる
- フロントエンド全般の文脈では、ブラウザが画面を描画すること(ブラウザレンダリング)
- Reactの文脈では、Reactが画面に表示する情報を得るための計算
- 正確にはJavaScriptの仕組みです。 ↩︎
- React公式の日本語ドキュメントの訳で「レンダー」が使用されていることがその理由です。 ↩︎
コメント