next.js 使用getServerSideProps时出错:由于初始UI与服务器上呈现的UI不匹配,因此协调失败

fkaflof6  于 2023-06-22  发布在  其他
关注(0)|答案(1)|浏览(133)

我正在使用Urql客户端向我的graphql服务器进行查询。我的查询看起来像这样:

const username = () => {
  const { t: translation } = useTranslation(["common", "profile"]);

  const { query, locale } = useRouter();
  const username = query.username;
  const [{ data: userProfileData }] = useUserProfileQuery({
    variables: {
      username: username as string,
    },
    pause: isServer || !username,
  });
  const userProfile = userProfileData?.userProfile;

  return (
    <Text>{userProfile.name}</Text>
  );
};

export default withUrqlClient(createUrqlClient, { ssr: false })(username);

这很好,但是因为我使用next-i18next库来本地化我的网站,所以我必须添加getServerSideProps函数。

export const getServerSideProps = async ({ locale, locales}: any) => {
  return {
    props: {
      ...(await serverSideTranslations(
        locale,
        ["common", "profile", "settings"],
        null,
        locales
      )),
    },
  };
};

这一切工作正常,但这意味着我不能通过将ssr设置为true来呈现我的页面,如下所示:

export default withUrqlClient(createUrqlClient, { ssr: false })(username);

我的目标是在useUserProfileQuery服务器上进行查询。
我读了以下指南:https://formidable.com/open-source/urql/docs/advanced/server-side-rendering/#ssr-with-getstaticprops-or-getserversideprops。这建议我在getServerSideProps中进行查询。因此,新的getServerSideProps函数看起来像这样:

export const getServerSideProps = async ({ locale, locales, query }: any) => {
  const ssrCache = ssrExchange({ isClient: false });
  const client = initUrqlClient(createUrqlClient(ssrCache), false);
  if (client)
    await client
      .query(UserProfileDocument, {
        username: query.username,
      })
      .toPromise();

  return {
    props: {
      ...(await serverSideTranslations(
        locale,
        ["common", "profile", "settings"],
        null,
        locales
      )),
      urqlState: ssrCache.extractData(),
    },
  };
};

但是,我得到以下错误:

Error: Hydration failed because the initial UI does not match what was rendered on the server.

Warning: Expected server HTML to contain a matching <div> in <div>.

See more info here: https://nextjs.org/docs/messages/react-hydration-error

我做错了什么?请帮帮我

yx2lnoni

yx2lnoni1#

解决方案是在getServerProps中返回userProfile,并从username函数中删除查询。
以下是新的getServerProps的外观

export const getServerSideProps: GetServerSideProps = async ({
  locale,
  locales,
  query,
}: any) => {
  const ssrCache = ssrExchange({ isClient: false });
  const client = initUrqlClient(createUrqlClient(ssrCache), false);
  let userProfile = null;
  if (client)
    userProfile = await client
      .query(UserProfileDocument, {
        username: query.username,
      })
      .toPromise();

  return {
    props: {
      ...(await serverSideTranslations(
        locale,
        ["common", "profile", "settings"],
        null,
        locales
      )),
      userProfile: JSON.parse(JSON.stringify(userProfile?.data?.userProfile)),
    },
  };
};

这就是新的username函数的外观

const username = ({locale, userProfile}: any) => {
  const { t: translation } = useTranslation(["common", "profile"]);

  return (
    <Text>{userProfile.name}</Text>
  );
};
export default withUrqlClient(createUrqlClient, { ssr: false })(username);

相关问题