前言
近期使用React官方推荐的服务端渲染工具Next.js
进行服务端页面编程时遇到引入百度分享等外部JS
文件的问题。
Next.js
可以使用内置组件来装在 <head>
到页面中
import Head from 'next/head'
export default () =>
<div>
<Head>
<title>My page title</title>
<meta name="viewport" content="initial-scale=1.0, width=device-width" />
</Head>
<p>Hello world!</p>
</div>
那么我们就可以用这个特性引入外部js
文件了,下面是引入百度分享的例子:
import Head from 'next/head'
export default () =>
<div>
<Head>
<title>My page title</title>
<meta name="viewport" content="initial-scale=1.0, width=device-width" />
<script>
{
`
with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];
`
}
</script>
</Head>
</div>
这样就很好解决了怎么引入类似百度分享一类的外部js文件的问题,但是百度分享自身会存在一个问题:百度分享异步操作加载进页面的时候不会立即渲染,因为因为百度分享执行后,会创建全局的window.__bd_share_main,所以 需要在 ajax请求完成后执行一下window.__bd_share_main.init();
但是由于window操作是客户端行为,而Next.js自身是服务端渲染(SSR)的原因是没有window对象的,解决办法是利用Next.js动态导入,官方文档有说明,动态导入是可以禁止SSR
的,如下:
import dynamic from 'next/dynamic'
const DynamicComponentWithNoSSR = dynamic(import('../components/hello3'), {
ssr: false
})
export default () =>
<div>
<Header />
<DynamicComponentWithNoSSR />
<p>HOME PAGE is here!</p>
</div>
像官方文档一样动态引入百度分享所在组件即可解决问题了
// 禁止ssr
const ShareCol = dynamic(import('../components/sharecol'),{ssr:false})
百度分享组件中,在componentDidMount钩子函数中操作如下
componentDidMount(){
if(window._bd_share_main){
window._bd_share_main.init();
}
}
其他类似的外部引入问题也可以这样解决