我遇到以下错误:
Warning: Text content did not match. Server: "But I want to be altered by the client" Client: "Test"
in div (at pages/index.tsx:17)
in div (at pages/index.tsx:6)
in HomePage (at _app.tsx:5)
in MyApp
in Container (created by AppContainer)
in AppContainer
...具有以下设置:
NextJS应用程序组件:
function HomePage() {
return (
<>
<div id="test-div">I am rendered on the server.</div>
<script src="http://localhost:8080/bundle.js"></script>
</>
);
}
export default HomePage;
(注意:URL
http://localhost:8080/bundle.js
假定webpack-dev-server正在运行并提供该资源)随附的“示例”脚本:
const element = document.getElementById('test-div') as any;
element.innerHTML = 'But I want to be altered by the client';
在一个简单的设置中,我将只有一个静态html文件,声明一个div元素并包括“example”脚本。
但是我想使用NextJS,因为我想将动态(SSR)内容呈现到页面中(例如,来自cms的文本内容)。
我注意到,有时候(如果脚本执行需要花费更多的时间),就不会出现错误。只需在示例脚本中执行一些耗时的操作即可。
另一种骇人听闻的方法是在示例脚本中使用
setTimeout
。我不愿意这样做,直到我知道为什么会这样:
setTimeout(function() {
const element = document.getElementById('test-div') as any;
element.innerHTML = 'But I want to be altered by the client';
}, 20);
最佳答案
在服务器端渲染期间,浏览器和document
,window
对象不可用。
您可以在React组件安装后初始化用于处理DOM的脚本。
useEffect(() => init(), [])
要添加外部脚本,您可以执行以下操作:
useEffect(() => require('../babylon.js'), [])
要包含来自其他服务器的脚本,可以添加
script
标记:useEffect(() => {
const script = document.createElement("script");
script.src = "http://localhost:8080/bundle.js";
script.async = true;
document.body.appendChild(script);
},[])
如果要添加DOM监听器,则还需要进行清理。
Using the Effect Hook
Effects with Cleanup
关于node.js - 如何将dom操纵脚本包含到SSR Next.js App中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61296940/