[TIL #32] Next.js(SSR)+反応-応答エラー


Webを開発する過程で,反応型Web処理に遭遇することが多い.
reactの勉強を始めたばかりの頃はcss mediaで反応型処理が行われていましたが、なんといってもcssでいちいち実現するので不便(面倒なので)と感じたのでjsで反応型処理を行うreact-responsiveを使って実現しました.

最近TOYプロジェクトが行われていますが、今回は反応型ではなく、モバイルネットワークで実現したいだけなので、PC環境に登録する際に携帯電話で接続したいと思い、REACT-REACTIONを使って、下記のコードを書きました.
const isMobile = useMediaQuery({
    query: "(max-width:767px)"
});

// some codes...
<>
    {isMobile ?  
    <PageContainer></PageContainer> :
  	<MobileWarn/>}
</>
isMobileは、移動環境で一時(width>767 px)trueを返し、そうでなければfalseを返します.
私が考えているように、携帯電話でインターネットを利用するには<PageContainer></PageContainer>、パソコンでインターネットを利用するには<MobileWarn/>をレンダリングします.
しかし、携帯電話で接続すると、2つの素子が混在し、奇妙な様子で画面に現れ、奇妙な状況に直面している.
何が問題なのか...ハニープロジェクトを実施する際にはNext.jsgetStaticPropsを利用してSSRを実現したが,これはreact-responsiveと出会い,問題となった.
NextのSSRは,サーバが応答コードをhtml,css,jsなどに変換する方式を示しており,最初の応答時にウィンドウオブジェクトが初期化されていないため,ウィンドウの情報(width,height.)データは参照なしで転送されます.
このため、isMobileを使用してモバイルとPCの2つの環境に分けて実現しても、リフレッシュ時に現れる画面は、ウィンドウ情報が分からないためデフォルトスタイルで現れる.
解決策は、SSRが実装されていても、クライアントがコンポーネントをインストールするときにisMobile変数の情報を更新することである.
// useState를 이용해서 isMobile state 생성
const [isMobile, setIsMobile] = useState(false);
const mobile = useMediaQuery({
    query: "(max-width:767px)"
});

useEffect(()=>{	// mobile 쿼리로 인해 값이 바뀔 때 수행
  if(mobile) setIsMobile(true);
},[mobile]);

// some codes...
<>
    {isMobile ?  
    <PageContainer></PageContainer> :
  	<MobileWarn/>}
</>
構成部品が取り付けられ、isMobileの状態が更新されて構成部品が再描画される場合、最初の要求に従って実施することができる.
また、上のコードはcustom hookなので使いやすいです.
export function useIsMobile () {
  const [isMobile, setIsMobile] = useState(false);
  const mobile = useMediaQuery({query: "(max-width:767px)"});
  
  useEffect(()=>{
    setIsMobile(mobile);
  },[mobile]);

  return isMobile;
}
ソース
ソース