[React講座] ReactコンポーネントとJSXの基本

当ページのリンクには広告が含まれています。
目次

ReactコンポーネントとJSXの基本

「コンポーネント」とは

Reactでは、画面の部品をコンポーネントとして定義します。

ざっくり言うと、「入力(props)を受け取って、JSX(見た目)を返すただの関数」です。

function Hello() {
  return <h1>Hello, React!</h1>
}
  • Hello がコンポーネント
  • 戻り値の <h1>〜</h1> が JSX
  • 使う側は HTML タグのように <Hello /> と書く

App.jsx で使うと:

// App.jsx
function Hello() {
  return <h1>Hello, React!</h1>
}

export default function App() {
  return (
    <div>
      <Hello />
      <p>Reactの世界へようこそ。</p>
    </div>
  )
}

ポイント:

  • コンポーネント名は 先頭を大文字 にする(Reactのルール)
  • <Hello /> のように、自分で作ったコンポーネントをタグ風に書く

JSXの正体と基本ルール

JSX = JavaScriptの中でHTMLっぽく書ける記法 です。
コンパイル時に普通の React.createElement(...) 呼び出しに変換されます。

ルール1:戻り値は「1つの親要素」にまとめる

これは React 初心者がかなりの確率で引っかかるポイントです。

// NG:これはエラーになる
function Bad() {
  return (
    <h1>タイトル</h1>
    <p>本文</p>
  )
}

JSXでは「隣り合う要素」はそのまま返せません。
必ず1つの親要素で包む必要があります。

function Good() {
  return (
    <div>
      <h1>タイトル</h1>
      <p>本文</p>
    </div>
  )
}

または、<> </> で囲む(フラグメント)方法もよく使います。

function Good() {
  return (
    <>
      <h1>タイトル</h1>
      <p>本文</p>
    </>
  )
}

ルール2:中括弧 {} の中にJS式を書ける

JSXの中では、中括弧 {} の中は JavaScript の世界です。

const name = 'Taro'
const count = 3

export default function App() {
  return (
    <div>
      <h1>こんにちは、{name} さん</h1>
      <p>カートの中身は {count} 個です</p>
      <p>2 + 3 = {2 + 3}</p>
    </div>
  )
}
  • {name} → 変数展開
  • {2 + 3} → 式の結果を埋め込み
  • {func()} → 関数の戻り値を埋め込み、もOK

if 文はそのまま書けないので、三項演算子などを使います(これは後で解説します)

ルール3:HTMLと微妙に違う属性名

JSXではいくつかの属性名が普通のHTMLと違います。

代表的なもの:

  • classclassName
  • for(labelの属性) → htmlFor
export default function App() {
  return (
    <div className="container">
      <label htmlFor="name">名前</label>
      <input id="name" type="text" />
    </div>
  )
}

理由は、classfor が JavaScript の予約語と絡むのと、DOMのプロパティ名に合わせているためです。

ルール4:属性値にJSを渡すときも {}

文字列だけなら "..." でOKですが、変数や数値、関数を渡すときは {} を使います。

const title = 'ダッシュボード'
const size = 32

export default function App() {
  return (
    <header>
      <h1 style={{ fontSize: size }}> {/* JSオブジェクトなので {{ }} になる */}
        {title}
      </h1>
      <img src="/logo.png" alt="logo" />
    </header>
  )
}
  • style はオブジェクトなので {{ fontSize: size }} と二重波括弧になる(外側:JSXの {}, 内側:JSオブジェクトの {}
  • src="/logo.png" はただの文字列なので {} はいらない

props:コンポーネントの「引数」

コンポーネントに値を渡したいときは、属性として書く ⇒ props で受け取る という形を取ります。

function Greeting(props) {
  return <p>こんにちは、{props.name} さん!</p>
}

export default function App() {
  return (
    <div>
      <Greeting name="太郎" />
      <Greeting name="花子" />
    </div>
  )
}
  • <Greeting name="太郎" /> で、name という属性を渡している
  • Greeting コンポーネントでは props.name として参照できる

よく使う書き方として 分割代入 があります:

function Greeting({ name }) {
  return <p>こんにちは、{name} さん!</p>
}

props オブジェクトから name プロパティだけ抜き出して受け取るイメージです。

複数のpropsを渡す例

function UserCard({ name, age, isActive }) {
  return (
    <div className="user-card">
      <h2>{name}</h2>
      <p>年齢: {age}</p>
      <p>ステータス: {isActive ? 'アクティブ' : '休止中'}</p>
    </div>
  )
}

export default function App() {
  return (
    <>
      <UserCard name="山田太郎" age={28} isActive={true} />
      <UserCard name="佐藤花子" age={34} isActive={false} />
    </>
  )
}
  • age={28} のように、数値や真偽値は {} で渡す
  • isActive ? 'アクティブ' : '休止中' で三項演算子を使って表示を切り替え

コンポーネントの分割とファイル分け

規模が大きくなると、1ファイルに全部書くとすぐにカオスになります。
Reactでは、「1つのUIパーツ = 1コンポーネント = 1ファイル」くらいの粒度で分解していくのが基本です。

例:ユーザー一覧画面をざっくり構成すると

  • App.jsx … 全体のレイアウト
  • UserList.jsx … ユーザーの一覧部分
  • UserItem.jsx … 各ユーザー1件の表示

UserItem.jsx

// src/UserItem.jsx
export default function UserItem({ user }) {
  return (
    <li className="user-item">
      <strong>{user.name}</strong>({user.email})
    </li>
  )
}

UserList.jsx

// src/UserList.jsx
import UserItem from './UserItem'

export default function UserList({ users }) {
  return (
    <ul>
      {users.map((u) => (
        <UserItem key={u.id} user={u} />
      ))}
    </ul>
  )
}

App.jsx

// src/App.jsx
import UserList from './UserList'

const dummyUsers = [
  { id: 1, name: '山田太郎', email: 'taro@example.com' },
  { id: 2, name: '佐藤花子', email: 'hanako@example.com' },
]

export default function App() {
  return (
    <div>
      <h1>ユーザー一覧</h1>
      <UserList users={dummyUsers} />
    </div>
  )
}

ポイント:

  • コンポーネントを細かく分けることで、
    • ロジックの見通しがよくなる
    • 再利用しやすくなる
    • テストもしやすくなる
  • export default したコンポーネントは import X from '...' で読み込む

条件分岐

JSX 内でよく使うパターンを1つだけ先取りしておきます。

条件に応じて表示を変える

function StatusBadge({ isOnline }) {
  return (
    <span className={isOnline ? 'badge online' : 'badge offline'}>
      {isOnline ? 'オンライン' : 'オフライン'}
    </span>
  )
}
  • クラス名もテキストも三項演算子で切り替え
  • 「UIは状態の関数」という感覚に慣れていくのに良い練習です

まとめ

  • コンポーネントは「入力⇒JSXを返す関数」
  • JSXの基本ルール:
    • 戻り値は1つの親要素で包む
    • {} でJS式を埋め込む
    • classclassName, forhtmlFor
  • props でコンポーネントにデータを渡し、再利用性の高いUIパーツを作っていく
  • ファイル分割しながら、小さい部品に分けていくのが基本

<<前へ(Node.js・npm・ビルドツールの基礎)

>>次へ(イベント処理と状態管理(useState))

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

コメント

コメントする

CAPTCHA


目次