如何使用 Remix 仅渲染组件客户端?

kem*_*ica 4 node.js reactjs server-side-rendering remix.run

我有一个只能在客户端呈现的 Three.js 组件,如何使用 Remix 来实现这一点?Remix 是否公开任何实用程序来帮助确定我们处于服务器还是客户端上下文中?找不到任何东西。

这是我尝试使用混音中不存在的虚构挂钩进行操作的示例。

import React from 'react';
import { useRemixContext } from '@remix-run/react';

const MyComponent = () => {
  const remixContext = useRemixContext();
  if(remixContext.server) {
     return null;
  }
  return <div>Should only be rendered on the client</div>
}
Run Code Online (Sandbox Code Playgroud)

kem*_*ica 8

人们可以使用库ClientOnly公开的组件remix-utils,该组件采用一个返回组件作为子组件的函数,该组件仅在客户端呈现。

该组件在内部使用钩子,useHydrated如果您不希望仅使用该组件进行客户端渲染,该钩子也会公开。

请注意,在开发模式下,这最初对我不起作用,我不知道这是因为我使用的是 remix-deno 模板,还是它通常不适用于实时重新加载,但一旦部署到生产环境中,它就会起作用。就像魅力一样。

import React from 'react';
import { ClientOnly } from "remix-utils";

const App = () => {
  return <ClientOnly fallback={null}>
     {() => <MyComponent/>}
  </ClientOnly>
}
Run Code Online (Sandbox Code Playgroud)

另请注意,Suspense最终将发布它,它将取代上述代码。


小智 5

remix-utils 不支持最新版本的 remix,即 2.x。我可以通过使用 React Suspense 和惰性函数来解决它。

import type { MetaFunction } from "@remix-run/cloudflare";
import React, { lazy, Suspense } from "react";
import "easymde/dist/easymde.min.css";

let SimpleMDE = lazy(async () => {
  const module = await import("react-simplemde-editor");

  return { default: module.default };
});
const MemoizedMDE = React.memo(SimpleMDE);

export default function Index() {
  return (
    <div>
      <h1>Simple MDE</h1>
      <Suspense fallback={<div>Loading...</div>}>
        <MemoizedMDE />
      </Suspense>
    </div>
  );
}
Run Code Online (Sandbox Code Playgroud)