渲染需要 window 个对象的同构 React 组件
Render isomorphic React component which requires window object
我有一个同构的 React 应用程序,组件在服务器端呈现。我希望使用第 3 方 React 组件:(GraphiQL),并且正在渲染:
var GraphiQLComponent = React.createElement(GraphiQL, { fetcher: graphQLFetcher}, "");
router.get('/graphiql', function (req, res) {
res.send(ReactDOMServer.renderToString(GraphiQLComponent));
});
但是,此组件使用 window 对象:window.localStorage
和 window.addEventListener
,当我尝试在浏览器中加载页面时,出现错误:
ReferenceError: window is not defined
我可以在服务器上渲染使用 window 对象的 React 组件吗?如果是这样,我需要做什么来解决这个错误?
不要在组件中使用依赖于 window 的库。
要么
仅在 componentDidMount
中使用这些库,并在 prerendering 中排除它们(确保您的组件在预渲染时不会呈现不同或不起作用)。
我认为我不应该在 class 定义之外导入库,而是在 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();
}
...
}
是的,你可以!
在定义 window 之前不要 运行 那段代码!
我还想象您可以在 componentDidMount() 生命周期函数中使用这些函数。
if (window !== 'undefined') {
// do your window required stuff
}
我已经在服务器端渲染的组件中多次使用它,它的效果非常好。
我有一个同构的 React 应用程序,组件在服务器端呈现。我希望使用第 3 方 React 组件:(GraphiQL),并且正在渲染:
var GraphiQLComponent = React.createElement(GraphiQL, { fetcher: graphQLFetcher}, "");
router.get('/graphiql', function (req, res) {
res.send(ReactDOMServer.renderToString(GraphiQLComponent));
});
但是,此组件使用 window 对象:window.localStorage
和 window.addEventListener
,当我尝试在浏览器中加载页面时,出现错误:
ReferenceError: window is not defined
我可以在服务器上渲染使用 window 对象的 React 组件吗?如果是这样,我需要做什么来解决这个错误?
不要在组件中使用依赖于 window 的库。
要么
仅在 componentDidMount
中使用这些库,并在 prerendering 中排除它们(确保您的组件在预渲染时不会呈现不同或不起作用)。
我认为我不应该在 class 定义之外导入库,而是在 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();
}
...
}
是的,你可以!
在定义 window 之前不要 运行 那段代码! 我还想象您可以在 componentDidMount() 生命周期函数中使用这些函数。
if (window !== 'undefined') {
// do your window required stuff
}
我已经在服务器端渲染的组件中多次使用它,它的效果非常好。