与客户端渲染相比,我更喜欢将服务器端渲染用于几乎没有用户交互的应用程序 . 而webpack是编译服务器端代码的选择 .
有一个场景我想在渲染组件后更新表的 marginTop . 如果是客户端呈现,则实现将如下所示
componentDidMount() {
const node = ReactDOM.findDOMNode(this.refs.table);
node.style.marginTop = `-${height}`;
}
但是,在ssr上,在呈现组件时永远不会调用 componentDidMount . 所以我将这些代码放在 componentWillMount 中,并按如下方式更新源代码
document.addEventListener("DOMContentLoaded", function(event) {
const node = document.getElementById('table');
node.style.marginTop = `-${height}`;
});
那还有其他问题 .
document is not defined on server
我知道原因,这是因为代码在节点环境中运行 . 没有 document 这样的浏览器环境 . 我能想到的一种方法是将代码放在 renderPage function 中,用于将React组件呈现给服务器端Server Rendering上的html字符串 . 但是如果将事件处理程序放在顶级上下文中,它将污染其他呈现的页面 .
router.get('*', ctx => {
match({ routes: routes, location: ctx.url }, (err, redirect, props) => {
if (err) {
ctx.throw(err.message, 500);
} else if (redirect) {
ctx.redirect(redirect.pathname + redirect.search)
} else if (props) {
const appHtml = renderToString(<RouterContext {...props}/>);
ctx.body = renderPage(appHtml);
} else {
ctx.throw(404, 'not fount');
}
})
})
function renderPage(appHtml) {
return `
<!doctype html public="storage">
<html>
<meta charset=utf-8/>
<title>My First React Router App</title>
<div id=app>${appHtml}</div>
<script type='text/javascript'>
document.addEventListener("DOMContentLoaded", function(event) {
const node = document.getElementById('table');
node.style.marginTop = `-${height}`;
});
</script>
`
}
我也找到了其他解决方案 . A React component for binding events on the global scope. . 我认为它不是最佳分辨率 .
所以我想问一下有没有更好的方法来操作DOM节点,这通常放在 componentDidMount 或 componentDidUpdate 中,就像客户端渲染一样 .
1 回答
像这样操纵DOM节点就像没用一样 . React接管你的DOM控件,在你下次重新渲染应用程序后,你设置的边距将被React覆盖 .
我建议你使用内联样式来操纵你喜欢的任何风格 .
还让渲染功能处理UI的东西 .
你有什么理由需要在React生命周期中重置marginTop而不是直接在渲染函数中重置吗?