Next.js と TypeScript で、Props.children を活用したコンポーネント作成

TwitterFacebookHatena

TL;DR

このページでは、Props.children の活用方法について解説します。Next.js と TypeScript を用いた具体的なコードサンプルを通じて、Props.children の概念とその活用法を学びましょう。

開発環境 バージョン
Next.js 13.4.3
TypeScript 5.0.4
Emotion 11.11.0
React 18.2.0

Props.children とは?

Props.children は、React のコンポーネントをより柔軟に再利用するためのテクニックです。これを使うと、親コンポーネントから子コンポーネントに動的に内容を渡すことが可能になります。

type CardProps = {
  title: string
}

const Card = ({ title, children }: CardProps & { children: React.ReactNode }) => {
  return (
    <div>
      <h2>{title}</h2>
      <div>{children}</div>
    </div>
  )
}

上記の例では、Card コンポーネントは title プロパティを受け取りますが、加えて children プロパティも受け取ります。これにより、Card コンポーネントの利用者は自由に子要素を追加できます。

Next.js で、Props.children を活用

ここでは、実際に Next.js と TypeScript を使って、Props.children を活用したコンポーネント作成をしてみましょう。

// components/Layout.tsx

import { ReactNode } from 'react'

type LayoutProps = {
  children: ReactNode
}

const Layout = ({ children }: LayoutProps) => {
  return (
    <div>
      <header>ここはヘッダーです</header>
      {children}
      <footer>ここはフッターです</footer>
    </div>
  )
}

export default Layout

ここでは、Layout コンポーネントを作成しました。このコンポーネントは、受け取った children をヘッダーとフッターの間に描画します。これにより、ページごとに異なる内容をヘッダーとフッターの間に描画できるようになります。

Props.children を活用

Props.children を活用することで、コンポーネントの再利用性を高めることができます。

特に、共通のスタイルや構造を持つコンポーネントを作成する際に便利です。

// components/Button.tsx

import { ReactNode } from 'react'

type ButtonProps = {
  children: ReactNode
}

const Button = ({ children }: ButtonProps) => {
  return <button>{children}</button>
}

export default Button

ここでは、Button コンポーネントを作成しました。このコンポーネントは、受け取った children をボタンの内部に描画します。これにより、ボタンのラベルを動的に設定することが可能になります。

Emotion で実装

CSS-in-JS ライブラリの一つである Emotion を使って、スタイル付きのコンポーネントを作成してみましょう。

// components/StylizedCard.tsx

/** @jsxImportSource @emotion/react */
import { css } from '@emotion/react'
import { ReactNode } from 'react'

type StylizedCardProps = {
  children: ReactNode
}

const StylizedCard = ({ children }: StylizedCardProps) => {
  return (
    <div
      css={css`
        border: 1px solid #ccc;
        padding: 20px;
        border-radius: 10px;
      `}
    >
      {children}
    </div>
  )
}

export default StylizedCard

この StylizedCard コンポーネントは、内部に何が描画されるかは Props.children に依存しますが、その外観は常に一定のスタイルを保証します。

map メソッドを使って配列データを描画

Props.children を用いると、配列データの描画も柔軟に行うことができます。具体的には、親コンポーネントから配列データを受け取り、子コンポーネントを動的に生成します。

// components/List.tsx

import { ReactNode } from 'react'

type ListProps = {
  children: ReactNode[]
}

const List = ({ children }: ListProps) => {
  return (
    <ul>
      {children.map((child, index) => (
        <li key={index}>{child}</li>
      ))}
    </ul>
  )
}

export default List

この List コンポーネントは、複数の子要素を受け取り、それぞれを li タグで囲んで描画します。こうすることで、動的にリストアイテムを生成することが可能になります。

// pages/index.tsx

import List from '../components/List'

const IndexPage = () => {
  return (
    <List>
      <span>リストアイテム 1</span>
      <span>リストアイテム 2</span>
      <span>リストアイテム 3</span>
    </List>
  )
}

export default IndexPage

このように、Props.children を用いると、親コンポーネントから子コンポーネントへのデータの流れを制御しやすくなり、より柔軟なコンポーネント設計が可能になります。特に配列データの扱いにおいては、その強力さを実感することができるでしょう。

Props.children を利用すると、コンポーネントの再利用性を高め、コードの冗長性を減らすことができます。特に Next.js と TypeScript を用いることで、より堅牢で型安全なコンポーネント作成が可能になるんですね。この概念を活用し、効率的なコンポーネント設計を行いましょう。

Next.js と TypeScript で、Props.children を活用したコンポーネント作成