Skip to main content
Version: 5.3

Our First Story

例えば、ホームページでブログ記事の最初の2〜3文を要約して表示し、全文を見るにはクリックする必要があるとします。

まず、この機能を実現するよう Article コンポーネントを更新してみましょう:

web/src/components/Article/Article.js
import { Link, routes } from '@redwoodjs/router'

const truncate = (text, length) => {
return text.substring(0, length) + '...'
}

const Article = ({ article, summary = false }) => {
return (
<article className="mt-10">
<header>
<h2 className="text-xl text-blue-700 font-semibold">
<Link to={routes.article({ id: article.id })}>{article.title}</Link>
</h2>
</header>
<div className="mt-2 text-gray-900 font-light">
{summary ? truncate(article.body, 100) : article.body}
</div>
</article>
)
}

export default Article

コンポーネントに追加の summary props を渡して、要約だけを表示するか、全体を表示するかを知らせます。デフォルトは false で、既存の挙動を維持 -- つまり常に本文を表示します。

それではStorybook で summary ストーリーを作りましょう。これは generated と同じように Article コンポーネントを使うものの、 新しい summary props を追加したものです。 サンプルポストの内容を定数に格納し、両方のストーリーで使うことにします。また、両者の違いを明確にするために、generatedfull にリネームします:

web/components/Article/Article.stories.js
import Article from './Article'

const ARTICLE = {
id: 1,
title: 'First Post',
body: `Neutra tacos hot chicken prism raw denim, put a bird on it enamel pin post-ironic vape cred DIY. Street art next level umami squid. Hammock hexagon glossier 8-bit banjo. Neutra la croix mixtape echo park four loko semiotics kitsch forage chambray. Semiotics salvia selfies jianbing hella shaman. Letterpress helvetica vaporware cronut, shaman butcher YOLO poke fixie hoodie gentrify woke heirloom.`,
}

export const full = () => {
return <Article article={ARTICLE} />
}

export const summary = () => {
return <Article article={ARTICLE} summary={true} />
}

export default { title: 'Components/Article' }

変更を保存するとすぐにStorybookのストーリーが更新され、エラーが表示される場合があります:もう表示されるべき "Generated" なストーリーはありません!左側のツリーで "Article" を展開すると、 "Full" バージョンが表示されるはずです。 "Summary" をクリックすると、その違いがわかります:

image

Displaying the Summary

素晴らしい!では完璧に仕上げるために、ブログ記事を表示するホームページでこの要約を使ってみましょう。実際のホームページでは、参照は Article コンポーネントではなく ArticlesCell にあります。このように summary props を追加して、Storybook で結果を確認しましょう:

web/src/components/ArticlesCell/ArticlesCell.js
import Article from 'src/components/Article'

export const QUERY = gql`
query ArticlesQuery {
articles: posts {
id
title
body
createdAt
}
}
`

export const Loading = () => <div>Loading...</div>

export const Empty = () => <div>Empty</div>

export const Failure = ({ error }) => <div>Error: {error.message}</div>

export const Success = ({ articles }) => {
return (
<div className="space-y-10">
{articles.map((article) => (
<Article article={article} key={article.id} summary={true} />
))}
</div>
)
}

要約を実装した新しい一覧を見るにはストーリーをチェックしてください:

image

そして、実際のサイトを開くと、ここも概要が表示されています:

image

ArticleCell での Articlesummary props を含まないもの) の元々の使い方が、切り捨てられた(要約された)バージョンだけでなく、全体の投稿をレンダリングすることを再確認することができます:

image

Storybookは、コンポーネントを分離して作成および変更することを容易にし、実際にReactアプリケーションを構築する際の一般的なベストプラクティスにきちんと則るのに役立ちます:コンポーネントは、送信される props を変更するだけで自己完結し再利用可能でなければなりません。