Effect CommunityEC
Effect Community2y ago
48 replies
steida

Next.js Pages Router with RouterQuery

The same for Next.js Pages Router

import { Schema, parseOption } from "@effect/schema/Schema";
import { Option } from "effect";
import Error from "next/error";
import { useRouter } from "next/router";
import { ReactNode, useEffect, useMemo, useState } from "react";

/**
 * For Next.js Pages Router.
 * https://nextjs.org/docs/pages/api-reference/functions/use-router#router-object
 */
export const RouterQuery = <From, To>({
  schema,
  render,
}: {
  schema: Schema<From, To>;
  render: (query: To) => ReactNode;
}) => {
  const router = useRouter();
  const [query, setQuery] = useState<null | Option.Option<To>>(null);

  useEffect(() => {
    if (!router.isReady) return;
    setQuery(parseOption(schema)(router.query));
  }, [router.isReady, router.query, schema]);

  return useMemo(
    () =>
      query &&
      Option.match(query, {
        onNone: () => <Error statusCode={404} />,
        onSome: render,
      }),
    [query, render],
  );
};


Usage:

const DayProps = struct({ date: optional(DateFromUrlString) });
type DayProps = Schema.To<typeof DayProps>;

export const Day: FC = () => (
  <RouterQuery
    schema={DayProps}
    render={(props) => <DayWithProps {...props} />}
  />
);

const DayWithProps = memo<DayProps>(function DayWithProps(props) {
Was this page helpful?