iT邦幫忙

2022 iThome 鐵人賽

DAY 5
0
Modern Web

React 新手村 - 填坑記系列 第 5

React 新手村 - 填坑記 - Day5 開發問題(一)

  • 分享至 

  • xImage
  •  

在我自己目前的開發中,很常使用到window這一個函數

window.addEventListener("scroll", function() {
  console.log("scroll!")
});

但時常沒注意到位置,則會發生以下錯誤訊息
https://ithelp.ithome.com.tw/upload/images/20220917/20151676whZbIBbzwe.png
後來才發現造成這樣問題的主要原因,是我使用Nextjs它是一個具有Pre-rendering特性的React框架,
這也代表對於每一個頁面Nextjs都會嘗試先生成頁面HTML來獲得更好的SEO、使用體驗性...等,
在Nextjs生成頁面的過程中與Node.js呈現的關聯性導致該問題的發生,主軸也在於Node.js本身是沒有定義window這函數的,僅有window在瀏覽器中可用。

因此以下幾種為常見的處理方式

1. typeof

if(typeof window !== "undefined"){
    //browser code
}

這個方法是當系統無法取得window函數時,進行額外處理,來避免系統報錯。

2. useEffect hook

使用useEffect react hook主要是因為,僅會在渲染階段運行,所以它不會在服務器上面運作

import React,{ useEffect} from "react"
export default function Scroll(){
    useEffect(function onFirstMount(){
        function onScroll(){
            console.log("scroll!")
        }
        window.addEventListener("scroll", onScroll)
    },[])//此處空dependencies參數,代表僅在第一次掛載時,運作一次
    return null;
}

3. dynamic loading(動態加載)

使用dynamic imports(動態加載)並且設定ssr:false來禁用服務器渲染,藉此使得component(組件)不會在服務器端呈現出來

 // components/Scroll.js

function onScroll() {
  console.log("scroll!");
}

window.addEventListener("scroll", onScroll);

export default function Scroll() {
  return null;
}
// pages/index.js

import dynamic from "next/dynamic";

const Scroll = dynamic(
  () => {
    return import("../components/Scroll");
  },
  { ssr: false }
);

export default function Home() {
  return (
    <div style={{ minHeight: "1000px" }}>
      <h1>Home</h1>
      <Scroll />
    </div>
  );
}

PS.如果有需要進行全局加載組件,並且在頁面切換時不再進行mount/unmount(掛載/卸載),可以設定在 _app.js 中加載需要的組件


上一篇
React 新手村 - 填坑記 - Day4 開發架構與邏輯(三)
下一篇
React 新手村 - 填坑記 - Day6 開發問題(二)
系列文
React 新手村 - 填坑記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言