【问题标题】:how to define global scope event handler for React server-side rendering如何为 React 服务器端渲染定义全局范围事件处理程序
【发布时间】:2017-04-04 01:20:07
【问题描述】:

与客户端渲染相比,对于用户交互很少的应用程序,我更喜欢使用服务器端渲染。而 webpack 是编译服务器端代码的选择。

有一个场景我想在组件渲染后更新表格的 marginTop。如果是客户端渲染,会列出如下实现

componentDidMount() {
  const node = ReactDOM.findDOMNode(this.refs.table);
  node.style.marginTop = `-${height}`;
}

但是,在 ssr 上,组件渲染时永远不会调用 componentDidMount。所以我把这些代码放在componentWillMount中,并更新源代码如下

document.addEventListener("DOMContentLoaded", function(event) {
  const node = document.getElementById('table');
  node.style.marginTop = `-${height}`;
});

那么它还有其他问题。

document is not defined on server 

我知道原因,是因为代码是在节点环境下运行的。没有像浏览器环境那样的 document 种类。我能想到的一种方法是将代码放在 renderPage 函数 中,该函数用于将 React 组件呈现为服务器端的 html 字符串 Server Rendering。但是如果将事件处理程序放在顶级上下文中,它会污染其他呈现的页面。

router.get('*', ctx => {
  match({ routes: routes, location: ctx.url }, (err, redirect, props) => {
    if (err) {
      ctx.throw(err.message, 500);
    } else if (redirect) {
      ctx.redirect(redirect.pathname + redirect.search)
    } else if (props) {
      const appHtml = renderToString(<RouterContext {...props}/>);
      ctx.body = renderPage(appHtml);
    } else {
      ctx.throw(404, 'not fount');
    }
  })
})
function renderPage(appHtml) {
  return `
    <!doctype html public="storage">
    <html>
    <meta charset=utf-8/>
    <title>My First React Router App</title>
    <div id=app>${appHtml}</div>
    <script type='text/javascript'>
      document.addEventListener("DOMContentLoaded", function(event) {
        const node = document.getElementById('table');
        node.style.marginTop = `-${height}`;
      });
    </script>
  `
}

我还找到了其他解决方案。 A React component for binding events on the global scope.。我不认为它是最好的分辨率。

所以我想问有没有更好的方法来操作通常放在 componentDidMountcomponentDidUpdate 中的 DOM 节点,如客户端渲染。

【问题讨论】:

    标签: node.js reactjs server-rendering react-server


    【解决方案1】:

    像你这样操作 DOM 节点是没有用的。 React 接管你的 DOM,下次你重新渲染你的应用程序后,你设置的边距将被 React 覆盖。

    我建议您使用内联样式来操作您喜欢处理的任何样式。

    render() {
      const divStyle={'marginTop': '100px'}
    
      return <div style={divStyle}></div>
    }
    

    还让渲染函数处理 UI 内容。

    是否有任何理由需要在 React 生命周期中重置 marginTop 而不是直接在渲染函数中?

    【讨论】:

      猜你喜欢
      • 2016-07-13
      • 1970-01-01
      • 2011-07-05
      • 1970-01-01
      • 1970-01-01
      • 2020-11-16
      • 1970-01-01
      • 1970-01-01
      • 2017-08-19
      相关资源
      最近更新 更多