Рендеринг изоморфного компонента React, для которого требуется объект окна

У меня есть изоморфное приложение React с компонентами, отображаемыми на стороне сервера. Я хочу использовать сторонний компонент React: (GraphiQL), и я отображаю как таковой:

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

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

Однако этот компонент использует объект окна: window.localStorage и window.addEventListener, и когда я пытаюсь загрузить страницу в браузере, я получаю сообщение об ошибке:

ReferenceError: window is not defined

Могу ли я визуализировать компоненты React, которые используют объект окна, на сервере? Если да, то что мне нужно сделать, чтобы устранить эту ошибку?


person christofr    schedule 22.10.2016    source источник


Ответы (2)


Не используйте библиотеки, которые зависят от окна в ваших компонентах. или Используйте эти библиотеки только в componentDidMount и исключите их для предварительного рендеринга (убедитесь, что ваш компонент не отображается иначе при предварительном рендеринге, иначе он не работает).

Я решил, что мне не следует импортировать библиотеку вне определения класса, а вместо этого требовать ее в методе 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();
    }
    ...
}
person Keshan Nageswaran    schedule 22.10.2016

Да, ты можешь!

Просто не запускайте этот фрагмент кода, пока окно не определено! Я также предполагаю, что вы могли бы использовать эти функции в функции жизненного цикла componentDidMount().

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

Я использовал это несколько раз в компонентах, отображаемых на стороне сервера, и это работает как шарм.

person jacoballenwood    schedule 22.10.2016