---
title: "JSS Next.jsアプリでのプレースホルダーの扱いについて"
slug: "working-with-placeholders-in-a-jss-next-js-app"
abstract: "Next.js JSSアプリケーションのためのプレースホルダー技術"
---
# JSS Next.jsアプリでのプレースホルダーの扱いについて

JSS Next.jsアプリでプレースホルダーを使う方法はいくつかあります。

> !ヒントプレースホルダーとは何か、どのように機能するかを理解するために、[JSSアプリのプレースホルダー](https://doc.sitecore.com/xp/ja/developers/hd/19/sitecore-headless-development/introducing-placeholders-in-jss-apps.html "Introducing placeholders in JSS apps") ガイドを読むことをお勧めします。

## 基本的なプレースホルダーの使い方

コンポーネントにプレースホルダーを追加する最も一般的な方法は、Placeholderコンポーネントを使うことです。

import { Placeholder } from '@sitecore-jss/sitecore-jss-nextjs';

const App = ({ rendering }) => (
 <div>
 <h1>My App</h1>
 <Placeholder name="jss-main" rendering={rendering} />
 </div>
);

Placeholder成分について:

-   nameは、あなたが露出させようとしているプレースホルダーの鍵です。
-   renderingは以下を表すことができます:
    -   現在のSitecore提供のレイアウト/ルートデータ。
    -   他のコンポーネント内でプレースホルダーを公開する場合は、親コンポーネントデータを使います。

## 高次成分法の使用

高次コンポーネント(HOC)パターンは、プレースホルダー内のコンポーネントの配列をプロパティとして注入し、プレースホルダーを露出させる仕組みです。

import { withPlaceholder } from '@sitecore-jss/sitecore-jss-nextjs';

const Tabs = ({ tabs }) => {
 return (
 <div>
 {tabs}
 </div>
 );
};

export default withPlaceholder('tabs')(Tabs);

コンポーネント配列を出力すると、アプリケーションはそのコンポーネントを出力した場所でレンダリングします。

HOC技術でプレースホルダーを発行すると、そのプレースホルダーにはラップコンポーネントがなく、インラインでレンダリングされます。HOCアプローチは *、特定のコンポーネント階層に基づく*ライブラリを使う場合に有用です。基本的なプレースホルダー技術を使うと、すべての子コンポーネントはコンポーネントツリーの下にレンダリングされます。

例えば、以下の構造でreact-fullpageライブラリを使いたい場合:

<SectionsContainer>
 <Section color="#69D2E7">Page 1</Section>
 <Section color="#A7DBD8">Page 2</Section>
 <Section color="#E0E4CC">Page 3</Section>
</SectionsContainer>

ライブラリは以下のコンポーネント階層を想定しています:

SectionsContainer
 Section

しかし、基本的なプレースホルダー技術でSectionコンポーネントを追加すると:

<SectionsContainer>
 <Placeholder name="jss-sections" rendering={rendering} />
</SectionsContainer>

その結果得られるコンポーネント階層は次のようになります:

SectionsContainer
 Placeholder
 YourComponent
 Section

HOCベースのプレースホルダーを使えば、インラインコンポーネントやコンポーネント変換を使って、よりフラットなコンポーネント階層を実現できます。

### インライン部品

ライブラリが単一のコンポーネントラップ層を禁止しない場合、以下のようなコンポーネント階層を得ることができます:

SectionsContainer
 YourComponent
 Section

子コンポーネントをレンダリングコンポーネントに配置できます。例えば:

import { withPlaceholder } from '@sitecore-jss/sitecore-jss-nextjs';

const ContainerComponent = ({ sectionsPlaceholder }) => {
 return <SectionsContainer>{sectionsPlaceholder}</SectionsContainer>;
};

// you can also alias the property for the placeholder when using the HOC - or pass an array of placeholders
export const ContainerSitecoreComponent = withPlaceholder({ placeholder: 'sections', prop: 'sectionsPlaceholder' })(ContainerComponent);

// the <Section> is in the child Sitecore component added to the placeholder
export const ChildSitecoreComponent = (props) => (
 <Section>
 <h1>Your components here</h1>
 </Section>
);

### コンポーネント変換

完全にフラットなコンポーネント階層を実現するために、例えば:

SectionsContainer
 Section

注入された性質が配列であることを利用し、子コンポーネントをラッパーで変換することができます。これはmap関数です。

子Sitecoreコンポーネントはラッピングを完全に認識せず、この技術を使う際に問題点を明確に分離するために自分のコンテンツのみをレンダリングできます。

例えば:

const ContainerComponent = ({ sectionsPlaceholder }) => {
 return (
 <SectionsContainer>
 {sectionsPlaceholder.map((component, index) => {
 // this if is important, as it prevents breakage when using Sitecore Experience Editor
 if (component.props && component.props.type === 'text/sitecore') return component;

 // wraps \_all\_ child components in a <Section> component
 return <Section key={index}>{component}</Section>;
 })}
 </SectionsContainer>
 );
};

export const ContainerSitecoreComponent = withPlaceholder({ placeholder: 'sections', prop: 'sectionsPlaceholder' })(ContainerComponent);

## レンダープロップス技術の使用

JSS高次コンポーネントの代替としてレンダープロップスパターンをサポートしています。<Placeholder>コンポーネントのrenderプロパティを使えば、高次コンポーネントと同様にプレースホルダーコンテンツのレンダリングを引き継ぎ、動的プロパティを利用できます。

以下の例は、コンポーネント配列を取得し、Propertiesを使ってレンダリングする方法render示しています。

import { Placeholder } from '@sitecore-jss/sitecore-jss-nextjs';

const App = ({ rendering }) => (
 <div>
 <h1>My App</h1>
 <Placeholder name="jss-main" rendering={rendering} render={(components, placeholderData, props) => <div>{components}</div>} />
 </div>
);

プレースホルダーのレンダリング関数に対して、オプションで2つの引数を使用できます:

-   propsパラメータは、<Placeholder>に渡される性質のミラーです。
-   placeholderDataパラメータは現在のプレースホルダーのレイアウトデータを提供します。

## 直接プレースホルダー内省技法

例えば、タブのように表示したいコンポーネント(タブタイトルとタブの内容)を2か所で表示したい場合、その構成要素ではなくプレースホルダーのデータにアクセスできます。プレースホルダー階層は大きなオブジェクトJavaScriptであるため、props.renderingを使って子コンポーネントデータやフィールドを発見できます。

const Tabs = ({ rendering, tabs }) => (
<Tab.Container>
 <div class="tabsHeading">
 {(rendering.placeholders.tabs || )
 .filter((tab) => tab && tab.fields && tab.fields.title)
 .map((tab, index) => (
 <Tab.Heading key={index}>
 <Text field={tab.fields.title} />
 </Tab.Heading>
 ))}
 </div>

 <div class="tabContents">
 {tabs}
 </div>
</Tab.Container>
);

export default withPlaceholder('tabs')(Tabs);

## プレースホルダーによる体験の向上

プレースホルダーはカスタムコンポーネントを使って開発者やエディタの体験を向上させるオプションを提供します。基本的なプレースホルダー技術を使うと、Placeholderコンポーネントプロパティを使って、プレイスホルダーがエラーやJavaScript実装の欠落をレンダリングするカスタムコンポーネントを設定できます。HOCパターンを使う場合は、propsTransformerオプションを使って関数を使って同じプロパティを注入できます。

### 誤差成分

プレースホルダーでレンダリングエラーが発生した場合、プレースホルダーはプレースホルダーの内容の代わりにエラーコンポーネントを表示し、エラーの詳細をコンソールに記録します。このコンポーネントは、errorComponentプロップを使ってカスタムコンポーネントを置き換えることでカスタマイズできます。

### 欠損コンポーネント

もしプレースホルダーにcomponentFactoryに知らないレンダリング名が含まれている場合(例えば、バックエンド開発者がFooレンダリングを作成しページに追加したが、まだFoo.jsがない場合)、レンダリングはコンポーネントのmissingComponentComponentプロパティで定義されたMissingComponentコンポーネントに置き換えられます。デフォルトの実装はシンプルなメッセージですが、missingComponentComponentプロパティのカスタムコンポーネントを使ってカスタマイズできます。