与客户端渲染相比,我更喜欢将服务器端渲染用于几乎没有用户交互的应用程序。而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
我知道原因,这是因为代码在节点环境中运行。浏览器环境没有文档种类。我能想到的一种方法是将代码放在 renderPage函数中,该函数用于将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 中,就像客户端渲染一样。
答案 0 :(得分:0)
像这样操纵DOM节点就像没用一样。 React接管你的DOM的控制权,在你下次重新渲染应用程序后,你设置的边距将被React覆盖。
我建议您使用内联样式来操作您想要处理的任何样式。
render() {
const divStyle={'marginTop': '100px'}
return <div style={divStyle}></div>
}
还让渲染功能处理UI内容。
是否有任何理由需要在React生命周期中重置marginTop而不是直接在渲染函数中重置?