← Files WixARCHIVED FILE

skills/wix-headless-templates/blog/project/src/hooks/blog/useComments.ts

1.52 KB · Oct 8, 2026 · 12:02 UTC

↓ Download file

See the change to this file →

// React binding of the comments store (wix/blog/comments-store.ts) — the thread state machine
// (cursor paging, replies on demand, create/delete as the current identity) lives there,
// framework-free; this hook subscribes to one instance per thread and exposes its state and actions.
//
// Mount the surface only when `post.commentingEnabled && post.referenceId`; pass the referenceId.
// Client-side by nature (the thread is read as the viewer) — in Astro, a `client:load` island.
import { useEffect, useRef, useSyncExternalStore } from "react";
import { createCommentsStore, type CommentsState, type CommentsStore, type CommentsStoreOptions } from "../../wix/blog/comments-store";

export type UseCommentsOptions = CommentsStoreOptions;

export type UseComments = CommentsState & Pick<CommentsStore, "loadMore" | "loadReplies" | "setSort" | "create" | "remove">;

export function useComments(options: UseCommentsOptions): UseComments {
  const ref = useRef<{ referenceId: string; store: CommentsStore } | null>(null);
  if (!ref.current || ref.current.referenceId !== options.referenceId) {
    ref.current = { referenceId: options.referenceId, store: createCommentsStore(options) };
  }
  const store = ref.current.store;
  useEffect(() => {
    store.start();
    return () => store.stop();
  }, [store]);
  const state = useSyncExternalStore(store.subscribe, store.getState, store.getState);
  return { ...state, loadMore: store.loadMore, loadReplies: store.loadReplies, setSort: store.setSort, create: store.create, remove: store.remove };
}

SHA-256: 8dec60fed3f2840a04958170f439c14e989756682c0bda7353c190dc5c131cf7