クライアント側のレンダリングと比較して、ユーザーの操作がほとんどないアプリケーションにはサーバー側のレンダリングを使用することを好みます。また、サーバー側のコードをコンパイルするには 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
理由はわかっています。コードがノード環境で実行されているためです。ブラウザ環境のようなドキュメントの多様性はありません。私が考えることができる方法は、React コンポーネントをサーバー側Server Renderingの html 文字列にレンダリングするために使用されるrenderPage 関数にコードを入れることです。しかし、イベント ハンドラーを最上位のコンテキストに配置すると、他のレンダリングされたページが汚染されます。
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>
`
}
私は他の解決策も見つけました。グローバル スコープでイベントをバインドするための React コンポーネント。. 私はそれが最善の解決策だとは思わない。
したがって、クライアント側のレンダリングのように、通常componentDidMountまたはcomponentDidUpdateに配置される DOM ノードを操作するより良い方法があるかどうかを尋ねたいと思います。