【问题标题】:Render isomorphic React component which requires window object渲染需要窗口对象的同构 React 组件
【发布时间】:2017-03-04 19:24:46
【问题描述】:

我有一个同构的 React 应用程序,组件在服务器端呈现。我希望使用第 3 方 React 组件:(GraphiQL),并且正在渲染:

var GraphiQLComponent = React.createElement(GraphiQL, { fetcher: graphQLFetcher}, "");

router.get('/graphiql', function (req, res) {
  res.send(ReactDOMServer.renderToString(GraphiQLComponent));
});

但是,这个组件使用了窗口对象:window.localStoragewindow.addEventListener,当我尝试在浏览器中加载页面时,我得到了错误:

ReferenceError: window is not defined

我可以在服务器上渲染使用 window 对象的 React 组件吗?如果是这样,我需要做什么来解决这个错误?

【问题讨论】:

    标签: javascript reactjs isomorphic-javascript graphql-js


    【解决方案1】:

    不要在组件中使用依赖于窗口的库。 要么 仅在 componentDidMount 中使用这些库并将它们排除在 prerendering 中(确保您的组件在 prerendering 中不会呈现不同或它不起作用)。

    我认为我不应该在类定义之外导入库,而是在 componentDidMount 方法或其被调用方法中需要它。

    所以,而不是:

    ...
    import MyWindowDependentLibrary from 'path/to/library';
    ...
    export default class MyClass extends React.Component {
        ...
        componentDidMount() { MyWindowDependentLibrary.doWork(); }
        ...
    }
    

    我做到了:

    // removed import
    ...
    export default class MyClass extends React.Component {
        ...
        componentDidMount() {
            const MyWindowDependentLibrary = require( 'path/to/library' );
            MyWindowDependentLibrary.doWork();
        }
        ...
    }
    

    【讨论】:

      【解决方案2】:

      是的,你可以!

      在定义窗口之前不要运行那段代码! 我还想象你可以在 componentDidMount() 生命周期函数中使用这些函数。

      if (window !== 'undefined') {
          // do your window required stuff
      }
      

      我已经在服务器端渲染的组件中多次使用它,它就像一个魅力。

      【讨论】:

        猜你喜欢
        • 2018-03-23
        • 2018-11-29
        • 2015-11-16
        • 2017-09-20
        • 2019-11-15
        • 2023-01-13
        • 1970-01-01
        • 2016-08-02
        • 2017-07-23
        相关资源
        最近更新 更多