我对样式化的组件感到非常兴奋,如果不适合使用它,我将很乐意使用它。
我已经使用next.js通用渲染库准备了两个示例项目。
第一个示例使用样式化的组件作为解决方案,第二个示例使用其css的默认解决方案,即styled-jsx。
这两个示例都包含完全相同的代码,且复杂度最低。
正如您很快就会看到的那样-在样式组件示例中,DOMContentLoaded事件和Load事件之间存在令人不安的延迟,在该延迟中,用户实际上看到了未样式化的html标记,而在第二个示例中,使用styled-jsx并不是案件。
这两个演示现在都使用Zeit在线托管:
1-https://01-styled-components-sqprkdqeft.now.sh
2-https://02-styled-jsx-nhrynpsdox.now.sh
来源可在github上找到:
1-https://github.com/Ajar-Ajar/next-demo--styled-components
2-https://github.com/Ajar-Ajar/next-demo--styled-jsx
我非常感谢您提供关于为何会在一个而不是另一个中发生的任何见解,
当然,也可以通过任何方式修改此行为,因为我希望使用样式化组件来实现其许多功能和优点。
谢谢
半开
:)
最佳答案
这里缺少的是服务器上的样式注入。基本上,当您使用JavaScript编写样式时,必须在服务器上获取生成的样式并将其作为style
标记注入到生成的HTML中。
Next的内置解决方案会自动为您执行此操作,使用styled-components
,您需要做一点点手工工作,并添加一个如下所示的pages/_document.js
文件:
import Document, { Head, Main, NextScript } from 'next/document'
import { styleSheet } from 'styled-components'
export default class MyDocument extends Document {
static async getInitialProps ({ renderPage }) {
const page = renderPage()
const styles = (
<style dangerouslySetInnerHTML={{ __html: styleSheet.rules().map(rule => rule.cssText).join('\n') }} />
)
return { ...page, styles }
}
render () {
return (
<html>
<Head>
<title>My page</title>
</Head>
<body>
<Main />
<NextScript />
</body>
</html>
)
}
}
注意我们如何注入来自
styled-components
的样式的样式标签。如此,无样式内容的闪烁消失了! 🎉(取自the official example)注意:v2版本的
styled-components
(即将推出,您可以通过`npm i --save styled-components @ next立即获得),它将有一个官方的SSR API,因此看起来更像这样:import Document, { Head, Main, NextScript } from 'next/document'
import styleSheet from 'styled-components/lib/models/StyleSheet'
export default class MyDocument extends Document {
static async getInitialProps ({ renderPage }) {
const page = renderPage()
const styles = (
<style dangerouslySetInnerHTML={{ __html: styleSheet.getCSS() }} />
)
return { ...page, styles }
}
render () {
return (
<html>
<Head>
<title>My page</title>
</Head>
<body>
<Main />
<NextScript />
</body>
</html>
)
}
}
希望有帮助!
关于css - 通用渲染会在DOMContentLoaded事件与Load事件之间创建延迟,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/42807221/