【问题标题】:Access variable from script inside React component从 React 组件内的脚本访问变量
【发布时间】:2018-08-30 06:47:46
【问题描述】:

从 React 组件中的脚本访问变量

我正在 Node 上进行设备检测并将这个对象发送到 index.ejs 内的客户端(React)

<script  type="text/javascript">window.deviceType = <%- deviceType %></script>

在 React 组件内部,如果我 console.log window.deviceType 我看到它运行良好,但如果我尝试使用它,它会显示 错误,未定义窗口。

比如这是在 react 组件里面

    return(
      <div>
       <Menu.Item>
         {window.deviceType.isMobile ? (
            <Link to="/">
                <h1>React Boilerplate 23</h1>
            </Link>
         ) : (
                 <div>PROBLEM</div>
          )}
        </Menu.Item>
        <div type="button" onClick={() => console.log(window.deviceType)}>
          XX
        </div>
       </div>
     )

我可以正常使用console.log,但是在使用逻辑时它不起作用,所以在上面的示例中渲染不起作用但console.log 起作用。

如果我尝试这样做,也会发生同样的事情

<script  type="text/javascript">var deviceType = <%- deviceType %></script>

【问题讨论】:

  • 是的。我使用 SSR。但是为了能够为移动或桌面呈现特定的东西,我检测节点上的设备并将其发送到客户端。是的,它所说的窗口没有定义,但如果我只是 console.log(window) 它工作正常。
  • 因为 onclick 回调中的代码仅在客户端进行评估。
  • 是的。我明白你的目标是什么。那么当代码是 SSR 时,如何使用脚本中的变量呢?

标签: javascript node.js reactjs window script-tag


【解决方案1】:

window 在浏览器中始终可用,原始代码不会导致客户端出现window is not defined 错误。只有在服务器端呈现 React 应用程序时才会发生这种情况。

window.deviceType.isMobile ? 表达式在服务器端进行评估,而onClick 回调在客户端调用,因此不会导致错误。

Node.js 中的global.window = global 不合适,因为该值不是全局的,而是特定于当前请求的。

正确的方法是将 deviceTypewindow 解耦,并以特定于 React 的方式为应用程序提供全局值,即通过 prop、state 或 context。可以从入口点将值作为道具传递。如果值正在使用中,则可以将其存储到 Redux 存储中。或者可以使用 React 上下文使其在应用程序中全局可用:

export const DeviceTypeContext = React.createContext();

...

<DeviceTypeContext.Consumer>
  {deviceType => (
   <Menu.Item>
     {window.deviceType.isMobile ? (...) : (
             <div>PROBLEM</div>
      )}
    </Menu.Item>
  )}
</DeviceTypeContext.Consumer>

在客户端:

render(
  <DeviceTypeContext.Provider value={window.deviceType}>
    <App />
  </DeviceTypeContext.Provider>,
  ...
);

在服务器端:

renderToString(
  <DeviceTypeContext.Provider value={someVariable}>
    <App />
  </DeviceTypeContext.Provider>,
  ...
);

【讨论】:

  • 谢谢你。这行得通。只是给正在做服务器端渲染的每个人的说明。请务必将相同的 deviceType 传递给 StaticRouter(react-router-4)。还要给 deviceType 一些默认值。这样,您可以在您的反应组件中使用“isMobile”、“isTablet”,并且当您执行 SSR 时,取决于您使用的设备,只有那些会被渲染到字符串。非常酷和干净的解决方案。
猜你喜欢
  • 1970-01-01
  • 2013-12-28
  • 1970-01-01
  • 2015-07-30
  • 1970-01-01
  • 2019-12-24
  • 2012-11-26
  • 1970-01-01
  • 2012-11-07
相关资源
最近更新 更多