首页 > 解决方案 > 有什么方法可以抑制 React.FC 中的水合警告?

问题描述

有什么方法可以抑制 React.FC 中的水合警告?我有一个警告,Did not expect server HTML to contain a <div> in <div>pause: isServer()我需要它来停止不断地向服务器请求。我可以以某种方式替换这个东西还是只supressHydrationWarning在这样的组件中使用?

export const NavBar: React.FC<NavBarProps> = ({}) => {  
  const [{ fetching: logoutFetching }, logout] = useLogoutMutation();
  const [{ data, fetching }] = useMeQuery({pause: isServer()}); 
  console.log(data);
  const router = useRouter();
  ...
};

是服务器:

export const isServer = () => typeof window === 'undefined';

导航栏在布局中:

import { Wrapper, WrapperVariant } from "./Wrapper";

interface LayoutProps {
  variant?: WrapperVariant;
}

export const Layout: React.FC<LayoutProps> = ({ children, variant }) => {
  return (
    <>
      <NavBar />
      <Wrapper variant={variant}>{children}</Wrapper>
    </>
  );
};

然后 Index 页面被包裹在 Layout 中

const Index = () => {
  const [variables, setVariables] = useState({
    limit: 15,
    cursor: null as null | string,
  });
  
  const [{ data, error, fetching }] = usePostsQuery({
    variables,
  });
  
  if (!fetching && !data) {
    return <div>query failed: {error?.message}</div>;
  }
  return (
    <Layout>
        ...
    </Layout>
  )
}

export default withUrqlClient(createUrqlClient, { ssr: true })(Index);
...

...并在打开 ssr 的情况下导出。

我正在将 Next.JS 与 Chakra-UI 一起使用,所以我认为它会呈现在这里?

import NextDocument, { Html, Head, Main, NextScript } from "next/document";
import { ColorModeScript } from "@chakra-ui/react";

export default class Document extends NextDocument {
  render() {
    return (
      <Html>
        <Head />
        <body>
          {/* Make Color mode to persists when you refresh the page. */}
          <ColorModeScript />
          <Main />
          <NextScript />
        </body>
      </Html>
    );
  }
}

标签: javascriptreactjstypescript

解决方案


pause选项在服务器和客户端上应该是相同的值。

const mounted = useMounted();

const [{ data, fetching }] = useMeQuery({pause: mounted === false}); 

检查组件是否已安装:

export const useMounted = () => {
  const [mounted, setMounted] = useState(false);

  useEffect(() => {
    setMounted(true);

    return () => {
      setMounted(false);
    };
  }, []);

  return mounted;
};

推荐阅读