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

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

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

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

React.js

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

Q&A

解決済

1回答

735閲覧

[React] 「投稿がありません」コメントの最適なロジックがわからない

DaisukeMori

総合スコア226

JavaScript

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

React.js

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

0グッド

0クリップ

投稿2020/05/18 08:23

編集2020/05/18 15:35

#前提

  • React
  • データベースはFirestore(Firebaseのcloud datebase)
  • 投稿記事のvalueにFirebase Authenticationのuidをアップして連携可能にしている

悩み

現在SNSアプリの仕組みを実装している中
投稿がない場合、「投稿がありません」と1文を出したいのですが、
配列ループで出しているため、リスト分「投稿がありません」と表示されてしまいます。

イメージ説明
ログイン(auth)投稿者以外の記事分、表示されてしまう。

要件(まとめ)

authユーザーの記事のみ表示 ← これのみならすでに可能
かつ(追加したい要件)
もし記事がなかったら「投稿がありません」の1文を1個のみ表示

jsx

1// 問題の箇所抽出 2{list.map(item => ( 3 <React.Fragment key={item.docId + String(new Date())}> 4 {authId === item.authId ? ( 5 <div>{item.msg}</div> 6 ) : ( 7 {/* ループの中に入っているためリスト分表示されてしまう */} 8 <div> 9 投稿がありません 10 </div> 11 )} 12 </React.Fragment> 13))}

jsx

1// コード全文 2import React from 'react'; 3import firebase, { db } from '../../Firebase'; 4import { useCollectionData } from "react-firebase-hooks/firestore"; 5 6const Index = () => { 7 // Firebese Auth uid, email取得 8 const user = firebase.auth().currentUser; 9 let authId; 10 let name; 11 let photoURL; 12 13 if (user != null) { 14 user.providerData.forEach(() => { 15 authId = user.uid; 16 name = user.displayName; 17 photoURL = user.photoURL; 18 }); 19 } 20 21 // Render 22 const [ list, loading, error ] = useCollectionData(db.collection('posts').orderBy('createdAt', 'desc'), { idField: 'docId' }); 23 24 if (loading) return <div>Loading...</div>; 25 if (error) return <div>Error...</div>; 26 const result = Object.keys(list).length; // Countを数える 27 console.log(result); 28 29 // Delete 30 const handleDelete = (uid) => { 31 if (window.confirm('削除しますか?')) { 32 db.collection('posts').doc(uid).delete(); 33 } 34 } 35 36 return( 37 <React.Fragment> 38 <div className="post-list user-post-list"> 39 {list.map(item => ( 40 <React.Fragment key={item.docId + String(new Date())}> 41 {authId === item.authId ? ( 42 <div>{item.msg}</div> 43 ) : ( 44 <div> 45 投稿がありません 46 </div> 47 )} 48 </React.Fragment> 49 ))} 50 </div> 51 </React.Fragment> 52 ); 53} 54 55export default Index;

解決方法

アドバイスを受け無事表示できたので結果を載せておきます。

【うまくいった方法】

js側で投稿記事を抽出するロジックを書く
jsx側では表示のみにする

jsx

1// js側で抽出 2 // auth userの投稿記事のみ抽出 3 const result = list.filter((e) => { 4 return e.authId === authId; 5 }); 6 console.log(result); 7 const length = result.length; 8 console.log(length); 9 10{/* jsx側で表示 */} 11<div className="post-list user-post-list"> 12{length !== 0 ? ( 13 <React.Fragment> 14 {result.map(item => ( 15 <div key={item.docId + String(new Date())}> 16 <div className="auth-inner-post-list"> 17 <div className="auth-inner-post-text"> 18 <div className="post-msg">{item.msg}</div> 19 <span className="delete" onClick={() => handleDelete(item.docId)}>&gt; Delete...</span> 20 </div> 21 </div> 22 </div> 23 ))} 24 </React.Fragment> 25) : ( 26 <div className="no-user-posts">まだ記事が投稿されていません</div> 27)} 28</div>

jsx

1// コード全文 2import React from 'react'; 3import { Link } from 'react-router-dom'; 4import firebase, { db } from '../../Firebase'; 5import SignOut from '../FirebaseAuthHook/SignOut'; 6import { useCollectionData } from "react-firebase-hooks/firestore"; 7import BackTopIcon from '../../assets/img/backtop.png'; 8import UserIcon from '../../assets/img/user.png'; 9import styled from 'styled-components'; 10 11const BackTopStyle = styled.img` 12 width: 50px; 13 top: 25px; 14 left: 25px; 15 position: fixed; 16 zIndex: 11, 17`; 18 19const Index = () => { 20 // Firebese Auth uid, email取得 21 const user = firebase.auth().currentUser; 22 let authId; 23 let name; 24 let photoURL; 25 if (user !== null) { 26 user.providerData.forEach(() => { 27 authId = user.uid; 28 name = user.displayName; 29 photoURL = user.photoURL; 30 }); 31 } 32 33 // Render 34 const [ list, loading, error ] = useCollectionData(db.collection('posts').orderBy('createdAt', 'desc'), { idField: 'docId' }); 35 if (loading) return <div>Loading...</div>; 36 if (error) return <div>Error...</div>; 37 38 // auth userの投稿記事のみ抽出 39 const result = list.filter((e) => { 40 return e.authId === authId; 41 }); 42 console.log(result); 43 const length = result.length; 44 console.log(length); 45 46 47 // Delete 48 const handleDelete = (uid) => { 49 if (window.confirm('削除しますか?')) { 50 db.collection('posts').doc(uid).delete(); 51 } 52 } 53 54 return( 55 <React.Fragment> 56 <SignOut /> 57 <Link to="/"><BackTopStyle src={ BackTopIcon } alt="Topに戻る"/></Link> 58 59 <div className="user-wrapper"> 60 <div className="user"> 61 {photoURL ? ( 62 <img src={ photoURL } className="auth-user-icon" alt="User Thumbnail" /> 63 ) : ( 64 <img src={ UserIcon } className="auth-user-icon" alt="Firebase Thumbnail" /> 65 )} 66 <div className="user-datail"> 67 {name ? ( 68 <div className="user-name">{name}</div> 69 ) : ( 70 <div className="user-name">Firebaseユーザー</div> 71 )} 72 </div> 73 </div> 74 75 <div className="post-list user-post-list"> 76 {length !== 0 ? ( 77 <React.Fragment> 78 {result.map(item => ( 79 <div key={item.docId + String(new Date())}> 80 <div className="auth-inner-post-list"> 81 <div className="auth-inner-post-text"> 82 <div className="post-msg">{item.msg}</div> 83 <span className="delete" onClick={() => handleDelete(item.docId)}>&gt; Delete...</span> 84 </div> 85 </div> 86 </div> 87 ))} 88 </React.Fragment> 89 ) : ( 90 <div className="no-user-posts">まだ記事が投稿されていません</div> 91 )} 92 </div> 93 </div> 94 </React.Fragment> 95 ); 96} 97 98export default Index;

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

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

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

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

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

guest

回答1

0

ベストアンサー

配列ループで出しているため、リスト分「投稿がありません」と表示されてしまいます。

  • 事前に配列をfilterして、表示すべき分だけに絞り込んでおく
  • filter後の配列をmapして出力
  • 1つもなければ「ありませんでした」メッセージを表示

のようにすればいいかと思います。上の階層で処理すべき場面です。

投稿2020/05/18 08:26

maisumakun

総合スコア146018

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

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

DaisukeMori

2020/05/18 15:31

ありがとうございました。事前にロジックを組んでおくのですね。 一応うまくいったコードを投稿部分の下部に載せておきます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問