チャベログ

easy-notion-blogにいいねボタンを追加する

画像が読み込まれない場合はページを更新してみてください。

ある日、easy-notion-blogの開発者であるおとよさんが以下のツイートをしていました。

挑戦してみることにしました。

いいねボタンを追加する

おとよさんの記事を見ながら追加したら全く困ることなく追加できました。

画像が読み込まれない場合はページを更新してみてください。

いいね数を表示する

勉強がてら、いいね数を表示してみました。

画像が読み込まれない場合はページを更新してみてください。
CSSの調整
+  import styles from '../styles/like-button.module.css'
src\components\like-button.tsx
+  <button onClick={handleClick}>Like</button>
-  <button onClick={handleClick} className={styles.likeButton}></button>
src\components\like-button.tsx

以下全て追加。

.likeButton {
  background-color: transparent;
  border: none;
  font: inherit;
  line-height: 1rem;
  font-size: 1rem;
  cursor: pointer;
  background-color: rgb(231, 76, 60);
  color: white;
  padding: 0.5rem;
  border-radius: 0.4rem;
}

.likeButton:active {
  opacity: 0.6;
}
src\styles\like-button.module.css

これで、以下のような見た目になりました。

画像が読み込まれない場合はページを更新してみてください。
いいね数を追加する

まずは現状確認を行います。

<LikeButton slug={post.Slug}/>
src\pages\blog\[slug].tsx

LikeButtonslug={post.Slug}を渡しているようです。

console.logpostの中身を確認します。

{
  PageId: '3617d1d3-6176-4cdd-baf5-9f0396f96bde',
  Title: 'easy-notion-blogにお問い合わせページを入れてみた',
  Slug: 'noway-form',
  Date: '2022-07-17',
  Tags: [ 'easy-notion-blog', 'Notion Tools' ],
  Excerpt: 'Noway Formというサービスを使ってeasy-notion-blogにお問い合わせフォームを入れてみました。',
  OGImage: 'https://s3.us-west-2.amazonaws.com/secure.notion-static.com/dfb3caa9-fcb6-4320-8fef-64c3ea29647c/noway-form.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Content-Sha256=UNSIGNE
D-PAYLOAD&X-Amz-Credential=AKIAT73L2G45EIPT3X45%2F20220718%2Fus-west-2%2Fs3%2Faws4_request&X-Amz-Date=20220718T020105Z&X-Amz-Expires=3600&X-Amz-Signature=a34b55e5be80ef86f71f98cf04fbec4
f6b8cedc6c1eec4dc782abd6d756df74d&X-Amz-SignedHeaders=host&x-id=GetObject',
  Rank: 8,
  Like: 1
}

slug={post.Slug}Slug: 'noway-form'が入っています。

postLikeも入っているので、LikeButtonpostをまとめて渡すか、post.Likeを渡せばよさそうです。

今回はできるだけ変更を最小限にしたいので、post.Likeを渡すことにしました。

+  <LikeButton slug={post.Slug} post={post.Like}/>
-  <LikeButton slug={post.Slug}/>
src\pages\blog\[slug].tsx

LikeButtonの定義元を変更していきます。

   type Props = {
     slug: string;
+    post: string;
   }
src\components\like-button.tsx

postの型はnumberstringか迷いましたが、stringにしました。

(どちらがいいのだろう。。。どっちでも動く。)

続いて、

+  <button onClick={handleClick} className={styles.likeButton}>♥ {props.post ?? '0'} </button>
-  <button onClick={handleClick} className={styles.likeButton}></button>
src\components\like-button.tsx

{props.post ? props.post : '0'}でいいね数を表示します。

NotionのDBに値が入っていない場合はnullが返ってくるので、その場合は'0'を表示します。

Null 合体演算子 (??) を使えばすっきりかけました。

これでいいね数が表示できました。

画像が読み込まれない場合はページを更新してみてください。
いいね数がすぐに反映されない

いいねボタンをクリックするとNotionのDBにはすぐに反映されますが、記事上では1分ほど経過してから再読み込みをしないといいね数が反映されません。

いいね数が変更されたらNotion DBから再度いいね数を取得して反映するということをしないといけないのがわかりますが、今のところすぐにやり方がわからないので今後の課題です。

とりあえず苦し紛れに、注釈を追加することにしました。

+  <LikeButton slug={post.Slug} post={post.Like}/><span className={styles.help}> ←1分ほど経過して再読み込みするとクリックしたいいね数が反映されます。修正予定。</span>
-  <LikeButton slug={post.Slug} post={post.Like}/>
src\pages\blog\[slug].tsx
+  .help {
+    color:#9dacb7;
+  }
src\styles\blog.module.css
画像が読み込まれない場合はページを更新してみてください。
Jestのエラーが出る

何やらJestのエラーが出ています。

画像が読み込まれない場合はページを更新してみてください。
エラー内容と対応

一部抜粋ですが、全部同じ原因で起こっていると推測されます。

FAIL __tests__/lib/notion/client.test.ts
  ● getPosts › resolves 3 posts
    TypeError: Cannot read properties of undefined (reading 'number')
      643 |       prop.OGImage.files.length > 0 ? prop.OGImage.files[0].file.url : null,
      644 |     Rank: prop.Rank.number,
    > 645 |     Like: prop.Like.number,
          |                     ^
      646 |   }
      647 |
      648 |   return post
      at _buildPost (src/lib/notion/client.ts:645:21)
      at map (src/lib/notion/client.ts:57:18)
          at Array.map (<anonymous>)
      at Object.getPosts (src/lib/notion/client.ts:57:6)
      at Object.<anonymous> (__tests__/lib/notion/client.test.ts:11:17)

以下が重要と推測しました。

TypeError: Cannot read properties of undefined (reading 'number')
#中略
> 645 |     Like: prop.Like.number,
          |                     ^

どうやらLike: prop.Like.numberのところでprop.Likeundefinedにであるのに対して、numberでアクセスしようとしてるよということのようです。

ということで、prop.Likeundefinedであるときに0を入れるというように変更しました。

	const post: Post = {
	  PageId: data.id,
	  Title: prop.Page.title[0].plain_text,
	  Slug: prop.Slug.rich_text[0].plain_text,
	  Date: prop.Date.date.start,
	  Tags: prop.Tags.multi_select.map(opt => opt.name),
	  Excerpt:
	    prop.Excerpt.rich_text.length > 0
	      ? prop.Excerpt.rich_text[0].plain_text
	      : '',
	  OGImage:
	    prop.OGImage.files.length > 0 ? prop.OGImage.files[0].file.url : null,
	  Rank: prop.Rank.number,
+   Like: prop.Like != undefined ? prop.Like.number : 0,
-   Like: prop.Like.number,
	}
src\lib\notion\client.ts

無事エラーが無くなりました。

より良い対応

この記事を読んでくれたおとよさんが、より良い対応方法を教えてくれました。

ということで、以下の GitHub のリンクの通りの対応を行いました。

注意点としては、上記の対応を行った後にyarn testを行うと、スナップショットのエラーが出てしまいます。

yarn jest --updateSnapshotを実行すると、yarn test を行ってもエラーが無くなります。

これで無事git pushしてもエラーは無くなります。

対応した内容は以下です(上記のおとよさんのコミットと同じなので参考までに)。

終わりに

おとよさんのいいねボタンの追加方法の記事はかなり丁寧に解説してくれていて、初心者にとても寄り添ってくれている内容でした。

図解もかなりわかりやすかったです。

ただし、自分の場合は全ての内容がきちんと分かっているわけではないですし、今回できた課題のいいね数の即時反映についても勉強が必要かなと感じています。

JavaScript、React、TypeScript、Node.js、一からきちんと勉強しようと思います。

あと、Jestも。。。

以上です!

ありがとうございました!!

参考

今回のメインの参考記事
いいねボタンのCSS