0

クライアント側のレンダリングと比較して、ユーザーの操作がほとんどないアプリケーションにはサーバー側のレンダリングを使用することを好みます。また、サーバー側のコードをコンパイルするには 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 ノードを操作するより良い方法があるかどうかを尋ねたいと思います。

4

1 に答える 1