我正在构建一个同构应用程序,但我使用的是仅在客户端上呈现的第三方组件。所以,特别是对于这个组件,我只需要在客户端渲染时渲染它。
如何检测我是在客户端还是在服务器?我正在寻找类似isClient()
或的东西isServer()
。
我正在构建一个同构应用程序,但我使用的是仅在客户端上呈现的第三方组件。所以,特别是对于这个组件,我只需要在客户端渲染时渲染它。
如何检测我是在客户端还是在服务器?我正在寻找类似isClient()
或的东西isServer()
。
在内部,React 使用了一个ExecutionEnvironment
为此调用的实用程序。它实现了一些有用的属性,例如canUseDOM
和canUseEventListeners
。解决方案基本上就是这里所建议的。
实施 canUseDOM
var canUseDOM = !!(
(typeof window !== 'undefined' &&
window.document && window.document.createElement)
);
我像这样在我的应用程序中使用它
var ExecutionEnvironment = require('react/node_modules/fbjs/lib/ExecutionEnvironment');
...
render() {
<div>{ ExecutionEnvironment.canUseDOM ? this.renderMyComponent() : null }</div>
}
编辑这是一个不应直接使用的未记录功能。它的位置可能会因版本而异。我通过展示 Facebook 团队内部使用的内容来分享这一点,以此表达“这是你能做的最好的事情”。您可能希望将此代码(它很小)复制到您自己的项目中,这样您就不必担心在不同版本之间保持其位置或潜在的破坏性更改。
另一个编辑有人为此代码创建了一个npm 包。我建议使用那个。
npm install exenv --save
您可以使用 reacts lifecyle事件(例如:)componentDidMount
来检测服务器/客户端渲染。
import { useState, useEffect } from 'react'
function useIsServer () {
const [isServer, setIsServer] = useState(true)
useEffect(() => {
setIsServer(false)
}, [])
return isServer
}
用法
见下文(功能组件)
import useIsServer from './above'
function ServerOnly ({ children = null, onClient = null }) {
const isServer = useIsServer()
return isServer
? children
: onClient
}
用法
<ServerOnly
children='This String was rendered on the server'
onClient='This String was rendered on the client'
/>
class ServerOnly extends React.Component {
constructor (props) {
super(props)
this.state = {
isServer: true
}
}
componentDidMount() {
this.setState({
isServer: false
})
}
render () {
const { isServer } = this.state
const { children, onClient } = this.props
return isServer
? children
: onClient
}
}
用法
<ServerOnly
children='This String was rendered on the server'
onClient='This String was rendered on the client'
/>
可能相关的两件事:
许多项目使用一些约定来设置全局 SERVER 或 CLIENT 布尔值,因此您的所有代码都可以基于它进行切换。在你的服务器包中,设置一些全局,就像在这个项目中一样
global.__SERVER__ = true;
并在您的客户端包中,将一些全局客户端设置为 true,您可以使用 Webpack 的 DefinePlugin 的一种方式来实现
new webpack.DefinePlugin({
__CLIENT__: true
})
使用上述方法,您可以根据 willMount 或 render 中的变量进行切换,在服务器上做一件事,在客户端做另一件事。
在这里可能有用的第二件事是componentDidMount
仅在客户端上运行,而不是在服务器上运行。
您也可以使用componentDidMount()
,因为在服务器端呈现页面时不会运行此生命周期方法。