コメントサービスを実現する際に意識するデータ構造について
こんにちわ。nap5です。
コメントサービスを実現する際に意識するデータ構造についてサンプルとして紹介してみます。
コメントデータモデルを中心にサービスを考えるといい感じになるので、記事にしてみました。
元ネタは以下のデモになります。Reduxを使ったことがないので、今回はRecoilで実現してみました。
コメントのUIですが、引用リツイートのような構成にしてみました。
いわゆるインデントをつけるものだと幅がだんだん狭くなってしまいますので、リツイートの形式でやってみました。
Zennとかのコメントタイムラインはデータ構造は今回と同じ気はしますが、表示する際に少し工夫を入れているようです。
Product HuntもそのようなUIになっています。
デモコードです。
デモサイトです。
DBはSupabaseを使ってみました。RLSなどはしていないので、アドホックになります。なので、興味がある方は悪用厳禁でデモ用でお願いいたします。
実装する点でポイントになるのは以下になります。
Map型を使ってコメントID単位でアクセスできるデータ構造をサブとして用意する
一覧表示する際はvisitメソッドなどを使ってフラット化する
visitメソッドに関してはunistから提供されているようなものをイメージしています
削除機能は論理削除で代替する
フラグ制御になります
隠す機能も論理削除で代替する
フラグ制御になります
実現するにあたり以下のライブラリが重宝します。
データ構造は以下になります。
import { Simplify, SnakeCasedProperties } from 'type-fest'
export type Comment = {
id: string
type: 'root' | 'child'
parentId: string | null
author: string
text: string
isHidden: boolean
isDeleted: boolean
children: Comment[]
createdAt: string // 2023/5/7 12:42:36
updatedAt: string // 2023/5/7 12:42:36
}
export type CommentWithSibling = Simplify<
Comment & {
depth: number
siblingIndex: number | null
}
>
export type CommentForDB = SnakeCasedProperties<Comment>
自作しようと考えている方はこれを参考にチャレンジしてみてもいいかもですね。
すでに類似のサービスはいくつかあるので、それらを導入でもいいかもです。
簡単ですが、以上です。