質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Contentful

Contentfulは、グラフィカルなUIを提供しないAPIベースのヘッドレスCMSです。従来のCMSと異なり、ディスクトップやモバイルを始めとするさまざまなプラットフォームへのコンテンツ配信が可能なAPIが用意されています。

Gatsby

Gatsbyとは、Reactベースの静的サイトジェネレータ。最新のフロントエンド技術を活かし、機能豊富なWebサイトやアプリケーションを作ることが可能です。GraphQLを用いてあらゆるソースからサイトのデータを取得。指定した設定に基づいて静的サイトを構築することができます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

2回答

1454閲覧

[React]配列の中で配列を回す方法がわからない

r1_1092829

総合スコア17

Contentful

Contentfulは、グラフィカルなUIを提供しないAPIベースのヘッドレスCMSです。従来のCMSと異なり、ディスクトップやモバイルを始めとするさまざまなプラットフォームへのコンテンツ配信が可能なAPIが用意されています。

Gatsby

Gatsbyとは、Reactベースの静的サイトジェネレータ。最新のフロントエンド技術を活かし、機能豊富なWebサイトやアプリケーションを作ることが可能です。GraphQLを用いてあらゆるソースからサイトのデータを取得。指定した設定に基づいて静的サイトを構築することができます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

0クリップ

投稿2020/06/08 22:59

現在GatsbyとContentfulでブログアプリを作っているのですが、配列の仕方がわからず、どなたかご教示いただけると嬉しいです。

アプリは複数の関連タグをつけられるブログのようなもので(コード下部にgraphqlのクエリがあります)、
下記はindex.jsのソースコードで、<span className="post-basic-tagname">#タグ1</span>の部分に記事のタグを表示したいと思っています。
ただ記事には複数のTagが付与されるため、配列で渡ってきているはずのtagsをループ処理して表示する方法がわかりません。
mapも試してみましたがうまくいきません。
#タグ1の部分に{post.tags}と書いてみると、
Error: Objects are not valid as a React child (found: object with keys {name, slug}). If you meant to render a collection of children, use an array instead.
というエラーが出るので、配列ではあるようなのですが、これをblogPosts.map(({ node: post }) => (の中で、さらにループ処理?してうまく表示する方法がわかりません・・・。

const IndexPage = ({ data }) => { const blogPosts = data.allContentfulBlogArticle.edges; return ( <Layout> <div className="post-basic"> { blogPosts.map(({ node: post }) => ( <div className="post-basic-item"> <img src={post.thumbnail.file.url} alt="Slide1" className="thumbnail" /> <div className="post-basic-textblock"> <p className="post-basic-postedat">{post.createdAt}</p> <h3><Link to={`/post/${post.slug}`}>{post.title}</Link></h3> <p>{post.content.content}</p> <div className="post-basic-catbox"> <span className="post-basic-catname">{post.category}</span> <span className="post-basic-tagname">#タグ1</span> <span className="post-basic-tagname">#タグ2</span> <span className="post-basic-tagname">#タグ3</span> </div> </div> </div> )) } </div> </Layout> ); }; export default IndexPage; export const query = graphql` query BlogArticleQueryTop { allContentfulBlogArticle(filter: {node_locale: {eq: "ja-JP"}}) { edges { node { id title slug category content { content } thumbnail { file { url } } tags { name slug } createdAt } } } } `;

どうぞよろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

こんにちは

Error: Objects are not valid as a React child (found: object with keys {name, slug}). If you meant to render a collection of children, use an array instead.

というエラーメッセージから、post.tags の要素が通常のプレーンオブジェクトであるにも関わらず

jsx

1<span className="post-basic-tagname">{post.tags}</span>

としようとしたためのエラーと思われます。エラーメッセージにfound: object with keys {name, slug}とあるので、(とりあえず)以下のようにしてみるといかがでしょうか?

jsx

1<ul className="post-basic-tags"> 2 {post.tags.map(({ name, slug }) => 3 <li key={name}>name: {name}, slug: {slug}</li>) 4 } 5</ul>

CSSクラスも、post-basic-tagname を、複数形の post-basic-tags にしています。参考になれば幸いです。

追記1

post.tagsfalsy チェックを追加しました。

jsx

1<ul className="post-basic-tags"> 2 {post.tags && post.tags.map(({ name, slug }) => 3 <li key={name}>name: {name}, slug: {slug}</li>) 4 } 5</ul>

追記2

post.tags が null だったり、または undefiend だったりする可能性がある場合に、単に

jsx

1<ul className="post-basic-tags"> 2{post.tags.map(・・・

と書いてしまうと、 post.tags.map(・・・ のところで、 もし、post.tagsnull だと、 nullには mapメソッドは無いので、コメント頂きましたように

TypeError: Cannot read property 'map' of null

というエラーになってしまいます。

なので、{・・・} の中には、

post.tags が null(や undefined) でない場合に、post.tags.map(・・・ を返す

という式を書かなければなりません。このようなときによく使うのが、先の追記1に書いた

{post.tags && post.tags.map(・・・

と書く方法です。これは&&による2つの式の結合

式1 && 式2

において、式1 が、Booleanに評価すればfalse になる値(falsyな値という。)の場合には、式2は評価されない(=関数やメソッドが使われていても、それらは実行されない)で、式1の値を、ただちに「式1 && 式2」という式全体を評価した値とすることを使っています。

これについて詳しく知るには、

の中の、「ショートサーキット評価」 (日本語では、短絡評価という。)を参照ください。今の例でいえば

{post.tags && post.tags.map(・・・

において、post.tags が null だったら、post.tags.map(・・・ は実行されずに、{・・・} の中の全体が null と評価されます。もし仮に、 && が短絡評価をしてくれなくて、post.tags が null であっても、&& の後ろの post.tags.map(・・・ を実行しようとするものだとしたら、やはり、Cannot read property 'map' of null でエラーになってしまいます。言い換えると、

{post.tags && post.tags.map(・・・

と書くことで、post.tags のfalsyチェックとして働く理由は、 && が短絡評価だから

と言えます。

post.tagsがnullの場合、post.tags && post.tags.map(・・・) 全体が null になることは、上記で説明したとおりですが、この場合は JSXでいうと、{・・・} の中が null ということになり、Reactの規則において、{・・・}の中がnullであっても許容される(≒JSXとして間違ってない)ので、この場合は、回答に書いたJSXの例でいうと、<li>がひとつもない <ul>がレンダーされます。

投稿2020/06/08 23:20

編集2020/06/09 00:36
jun68ykt

総合スコア9058

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

r1_1092829

2020/06/08 23:35

jun68ykt様 ご回答いただきありがとうございます。 早速いただいたコードをいれてみたところ、 TypeError: Cannot read property 'map' of null というエラーが出てしまうようでした。。
jun68ykt

2020/06/08 23:40

こんにちは コメントありがとうございます。 追記しましたように、 post.tags.map の前に post.tags && を追加すると、いかがでしょうか?
r1_1092829

2020/06/08 23:47

jun68ykt様 迅速な回答ありがとうございます。 post.tags &&を追加すると表示できました! 数時間悩んでいたので大変助かりました。ありがとうございます。 さらにお手間をかけて恐縮なのですが、 「post.tags の falsy チェックを追加」の意図が知りたく、 そちらの説明や情報ページがあればご教示いただけると嬉しいです。
jun68ykt

2020/06/09 00:26

どういたしまして???? > post.tags &&を追加すると表示できました! とのことでよかったです ???? > 「post.tags の falsy チェックを追加」の意図 について、回答に追記2 を書きました。参考になれば幸いです。
r1_1092829

2020/06/09 07:21

jun68ykt様 こちらも丁寧なご回答ありがとうございます! 確かに、記事をリスト化するページだったのですが、 一部記事はTagを持たないので、そのような処理が必要でしたね。。 お教えいただくまで気付きませんでした、大変勉強になりました。 この度はお時間を割いていただいてありがとうございました!!
guest

0

post.tags がタグの配列なら、以下のコードで行けるのでは。

diff

1 <div className="post-basic-catbox"> 2 <span className="post-basic-catname">{post.category}</span> 3- <span className="post-basic-tagname">#タグ1</span> 4- <span className="post-basic-tagname">#タグ2</span> 5- <span className="post-basic-tagname">#タグ3</span> 6+ {post.tags.map(tag => <span key={tag} className="post-basic-tagname">{tag}</span>)} 7 </div>

投稿2020/06/08 23:07

編集2020/06/08 23:08
hoshi-takanori

総合スコア7895

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

r1_1092829

2020/06/08 23:37

hoshi-takanori様 ご回答いただきありがとうございます。 早速いただいたコードに差し替えてみたところ、 TypeError: Cannot read property 'map' of null というエラーが出てしまうようでした。 ちなみにtagsの中にはnameとslugという子要素があり、どちらも表側に出したいのです・・・。 ``` tags { name slug } ```
r1_1092829

2020/06/08 23:50

hoshi-takanori様 こちら解決いたしました。 この度はお時間を割いていただきありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問