window 尝试访问 Remix 中的环境变量时未定义

window is not defined when trying to access environment variables in Remix

我正在尝试使用 Remix 将一些环境变量放入浏览器中,我一直在关注这个:

https://remix.run/docs/en/v1/guides/envvars

我完全按照步骤 1 和 2 进行了操作,但是我无法从浏览器访问 window.ENV。我收到此错误:ReferenceError: window is not defined

这是我非常简单的组件:

function Test() {
  console.log('Window: ', window);
  return <div>Hello, Test</div>;
}

export default Test;

如果我注释掉 console.log,我可以在文档顶部的 <body> 中看到 <script>,内容为 window.ENV = {...}。但是取消注释 console.log 向我显示错误消息并且没有 <script> 标记。这告诉我问题出在文档中设置 window.ENV 而不是我的组件中。

如有任何想法,我们将不胜感激!

在 React 的组件级范围内,如果不使用 useEffect 挂钩调用然后引用 [=13=,则无法访问 dom,其中 window 对象可见] 从那里。

您无法在该代码(组件渲染)中访问 window 对象,因为它 运行 在服务器(因为服务器端渲染)和客户端(只是作为常规客户端 React 应用程序)。在服务器上没有 window 对象或任何其他浏览器 API。因此,您需要以这种方式编写该代码,以便它可以在服务器和客户端上 运行。

您以后仍然可以使用 window 对象,例如在 useEffect 或某些 onClick 处理程序中,因为此代码只会在客户端 运行 :

// both this cases will work fine
  useEffect(() => {
    console.log(window.ENV);
  }, []);

// ...

      <button
        onClick={() => {
          console.log(window.ENV);
        }}
      >
        Log env
      </button>

但有时您直接在 render 方法中需要这些环境值。您可以将 loader 函数与 useLoaderData 挂钩结合使用,如下所示:

export function loader() {
  // process.env is available here because loader runs only on the server side
  return {
    SOME_SECRET: process.env.SOME_SECRET
  };
}

export default function Index() {
  const data = useLoaderData();

  // here you can use everything that you returned from the loader function
  console.log(data.SOME_SECRET);

  return <div>{/* ... */}</div>
}