はじめに
OZくん、前回までにコンポーネントの基本的な作り方は理解できましたか?
はい!コンポーネントは再利用可能なUIのパーツで、JSXを使って書くんですよね。でも先生、コンポーネントのデザインってどうやって付けるんですか?
いい質問ですね!今日はコンポーネントにスタイルを適用する方法と、コンポーネントを分割する方法について学んでいきましょう。
1.CSSでコンポーネントをスタイリングする
まずは簡単なコンポーネントを作って、スタイルを適用してみましょう。
import "./Example.css";
const Example = () => {
return (
<div className="component">
<h3>こんにちは!OZくん!</h3>
</div>
);
};
export default Example;
.component {
padding: 2rem;
color: red;
border: 5px solid green;
}
あれ?HTMLではclass=”component”って書いていたと思うんですけど、classNameになってるんですね?
よく気付きましたね!ReactではHTMLのclass
属性の代わりにclassName
を使います。これはJavaScriptで’class’が予約語として使われているためです。ちなみに、最新のReactでは、classと書いても問題なく動作するんですが、可読性を上げるために、classNameを使いましょう!
なるほど!でも、CSSファイルはどうやってコンポーネントと結びつけているんですか?
import "./Example.css";
それはimport "./Example.css"
の部分で行っています。このように直接CSSファイルをインポートすることで、そのコンポーネントにスタイルを適用できるんです。
2.コンポーネントを分割する
次は、コンポーネントを複数のファイルに分割する方法を見ていきましょう。まずは、なぜコンポーネントを分割するのか理解することが大切です。
どうして分割する必要があるんですか?
主に3つの理由があります。
- コードの管理がしやすくなる
- コンポーネントの再利用が簡単になる
- チームでの開発がスムーズになる
実際のコードを見ながら詳しく説明していきましょう。
// App.jsx
import Greeting from "./components/Greeting";
import Profile from "./components/Profile";
const App = () => {
return (
<div>
<Greeting />
<Profile />
</div>
);
};
export default App;
const Greeting = () => {
return (
<div>
<h1>こんにちは!</h1>
<p>ようこそReactへ!</p>
</div>
);
};
export default Greeting;
const Profile = () => {
return (
<div>
<h2>プロフィール</h2>
<ul>
<li>名前:OZくん</li>
<li>趣味:プログラミング</li>
</ul>
</div>
);
};
export default Profile;
ファイルが3つに分かれていて、Greeting.jsxとProfile.jsxのファイルはcomponentsフォルダに入っています。それぞれのファイルの役割を説明します。
App.jsx
- アプリケーションのメインとなるコンポーネント
- 他のコンポーネントを
import
して組み合わせています import Greeting from "./components/Greeting"
の部分で他のコンポーネントを読み込んでいます
Greeting.jsx
- 挨拶文を表示する部分を担当するコンポーネント
export default Greeting
で他のファイルから使えるようにしています
Profile.jsx
- プロフィール情報を表示する部分を担当するコンポーネント
- これも
export default Profile
で他のファイルから使えるようにしています
componentsフォルダを作っているのは何か理由があるんですか?
componentsフォルダを作る理由は、
- コンポーネントファイルを整理して管理しやすくする
- プロジェクトの構造を分かりやすくする
- チームの他のメンバーが必要なコンポーネントを見つけやすくなる
プロジェクトが大きくなるほど、このような整理整頓が重要になってきます。
なるほど!じゃあ、importとexportの書き方についてもう少し詳しく教えてください!
コンポーネントのインポート・エクスポートには2つの重要なポイントがあります。以下のコードを見てください。
1.エクスポート(export)の方法
// 方法1:デフォルトエクスポート
export default Greeting;
// 方法2:名前付きエクスポート
export const Greeting = () => { ... };
2.インポート(import)の方法
// デフォルトエクスポートされたものをインポートする場合
import Greeting from "./components/Greeting";
// 名前付きエクスポートされたものをインポートする場合
import { Greeting } from "./components/Greeting";
基本的には、1つのファイルには1つのコンポーネントを置き、export default
を使うのがシンプルで分かりやすいですよ。
なるほど!分かりました!!今日はありがとうございました!!
補足:exportとexport defaultの違い
// Example.jsx
import Child from "./components/Child";
const Example = () => {
return <Child />;
};
export default Example;
// Child.jsx
import "./Child.css";
import { List } from "./List.jsx";
const Child = () => {
return (
<div className="component">
<h3>コンポーネントを作ってみよう!</h3>
<List />
</div>
);
};
export default Child;
// List.jsx
const List = () => {
return (
<ul>
<li>項目-1</li>
<li>項目-2</li>
<li>項目-3</li>
<li>項目-4</li>
<li>項目-5</li>
</ul>
);
};
export { List };
/* Child.css */
.component {
padding: 1rem;
color: blue;
border: 5px solid blue;
}
export default
は、そのファイルのメインとなるコンポーネントを指定する時に使います。1ファイルに1つだけ使えます。- 普通の
export
は、複数のものをエクスポートでき、変数なども一緒にexportすることができます。インポートする時はimport { List } from './List'
のように波括弧{}を使う必要があります。
Fragmentについて
数日後、、、
プロ太先生!今日はReactの勉強中に困ったことがあるんです!
こんなコードを書いたんですけど、エラーになっちゃって…
const Child = () => {
return (
<div className="component">
<h3>こんにちは!OZくん</h3>
</div>
<h3>Fragmentを使ってみよう!</h3>
<p>エラーが出ずに出力できるかな?</p>
);
};
なるほど!これは多くの初学者がつまづくポイントですね。Reactのコンポーネントでは、returnする要素は必ず1つの親要素でまとめないといけないんです。なので、以下のようなコードに変更しましょう。
const Child = () => {
return (
<div>
<div className="component">
<h3>こんにちは!OZくん</h3>
</div>
<h3>Fragmentを使ってみよう!</h3>
<p>エラーが出ずに出力できるかな?</p>
</div>
);
};
divで囲って、1つの親要素でまとめる方法でエラーは解決できます!でも、これだと、必要のないdiv
要素が増えてしまいますよね。HTMLの構造が複雑になってしまうんです。
確かに…。でも他に方法はあるんですか?
そこで登場するのが「Fragment」です!まずは基本的な書き方を見てみましょう。
import React from "react";
const Child = () => {
return (
<React.Fragment>
<div className="component">
<h3>こんにちは!OZくん</h3>
</div>
<h3>Fragmentを使ってみよう!</h3>
<p>エラーが出ずに出力できるかな?</p>
</React.Fragment>
);
};
おお!余計なdiv
がなくなりました!でもReact.Fragment
って少し長くないですか?
その通り!もっと短く書く方法もあります。Fragment
を直接インポートする方法です。
import { Fragment } from "react";
const Child = () => {
return (
<Fragment>
{/* 中身は同じ */}
</Fragment>
);
};
そして、さらに簡単な書き方があります!空のタグ<></>
を使う方法です!
const Child = () => {
return (
<>
<div className="component">
<h3>こんにちは!OZくん</h3>
</div>
<h3>Fragmentを使ってみよう!</h3>
<p>エラーが出ずに出力できるかな?</p>
</>
);
};
わぁ!すっきりしました!これが一番簡単ですね!
そうですね。この空タグの書き方が最も一般的です。ちなみに、FragmentにはclassName
のようなスタイルに関する属性はつけることができないので、CSSを全体にあてたりはできません。
なるほど!!確かに全体を囲っているから、backgroundcolorとかつけてしまいそうです。でも、できないんですね。わかりました!!
ただ、実はkey
属性だけは特別で、<Fragment>
につけることができます。これはループ処理で要素を繰り返し表示する時によく使うんですが…これについては今後の「リストレンダリング」の回で詳しく説明しますね!今は、key属性だけ、<Fragment>
につけることができるということを理解しておいてください。
なるほど!!とりあえず今日は、空タグ<></>
を使えばいいんですね!
まとめ
では、今日学んだことを整理しておきましょう!
- コンポーネントのスタイリング
- CSSファイルをimportして使用する
- class属性の代わりにclassNameを使う
- コンポーネントの分割
- 複数のファイルに分けることで管理しやすくなる
- export defaultとexportを使い分ける
- コンポーネント間で組み合わせて使える
- フラグメントについて
- Reactのコンポーネントは必ず1つの親要素でまとめる必要がある
- 不要な
div
を避けるためにフラグメントを使用する - フラグメントは3つの書き方がある(
<React.Fragment>
、<Fragment>
、<></>
) - 通常は空タグ
<></>
を使うのがシンプルで推奨される書き方 - フラグメントには
className
などのスタイリング属性は使えない
わかりやすかったです!!次回も楽しみです!!