本文介绍了如何使用反应钩子检测 Next.js SSR 中的窗口大小?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

限时删除!!

我正在使用 Next.js 和 react-dates 构建应用.

我有两个组件 DateRangePicker 组件和 DayPickerRangeController 组件.

我想在窗口宽度大于 1180px 时渲染 DateRangePicker,如果尺寸小于这个,我想渲染 DayPickerRangeController.

代码如下:

 windowSize >1180?<日期范围选择器startDatePlaceholderText=开始"开始日期={开始日期}startDateId=开始日期"onDatesChange={handleOnDateChange}结束日期={结束日期}endDateId =结束日期"焦点输入={焦点}过渡持续时间={0}onFocusChange={(focusedInput) =>{如果(!focusedInput){setFocus(开始日期")} 别的 {setFocus(focusedInput)}}}/>:<DayPickerRangeControllerisOutsideRange={day =>isInclusivelyBeforeDay(day, moment().add(-1, 'days'))}开始日期={开始日期}onDatesChange={handleOnDateChange}结束日期={结束日期}焦点输入={焦点}onFocusChange={(focusedInput) =>{如果(!focusedInput){setFocus(开始日期")} 别的 {setFocus(focusedInput)}}}/>}

我通常使用带有 window 对象的 react hook 来检测窗口屏幕宽度,例如 this

但是我发现ssr的时候这种方式是不行的,因为ssr渲染没有window对象.

是否有另一种方法可以安全地获得窗口大小,而不管 ssr 是多少?

解决方案

通过添加以下代码,您可以避免在 ssr 中调用您的检测函数:

//确保你的函数只在客户端被调用如果(窗口类型!== '未定义'){//检测窗口屏幕宽度函数}

来自您链接的完整示例:

import { useState, useEffect } from 'react';//用法功能应用(){const size = useWindowSize();返回 (<div>{size.width}px/{size.height}px

);}//钩函数 useWindowSize() {//使用未定义的宽度/高度初始化状态,以便服务器和客户端呈现匹配//在此处了解更多信息:https://joshwcomeau.com/react/the-perils-of-rehydration/const [windowSize, setWindowSize] = useState({宽度:未定义,高度:未定义,});useEffect(() => {//只在客户端执行下面的所有代码如果(窗口类型!== '未定义'){//在窗口调整大小时调用的处理程序函数 handleResize() {//设置窗口宽度/高度为状态设置窗口大小({宽度:window.innerWidth,高度:window.innerHeight,});}//添加事件监听器window.addEventListener(resize", handleResize);//立即调用处理程序,以便使用初始窗口大小更新状态handleResize();//在清理时移除事件监听器返回 () =>window.removeEventListener(resize", handleResize);}}, []);//空数组确保效果只在挂载时运行返回窗口大小;}

I am building an app using Next.js and react-dates.

I have two component DateRangePicker component and DayPickerRangeController component.

I want to render DateRangePicker when the window's width is bigger than size 1180px, if the size is smaller than this I want to render DayPickerRangeController instead.

Here is the code:

      windowSize > 1180 ?
           <DateRangePicker
             startDatePlaceholderText="Start"
             startDate={startDate}
             startDateId="startDate"
             onDatesChange={handleOnDateChange}
             endDate={endDate}
             endDateId="endDate"
             focusedInput={focus}
             transitionDuration={0}
             onFocusChange={(focusedInput) => {
               if (!focusedInput) {
                 setFocus("startDate")
               } else {
                 setFocus(focusedInput)
                }
               }}
                /> :
             <DayPickerRangeController
               isOutsideRange={day => isInclusivelyBeforeDay(day, moment().add(-1, 'days'))}
               startDate={startDate}
               onDatesChange={handleOnDateChange}
               endDate={endDate}
               focusedInput={focus}
               onFocusChange={(focusedInput) => {
               if (!focusedInput) {
                 setFocus("startDate")
                 } else {
                  setFocus(focusedInput)
                 }
               }}
              />
          }

I normally use react hook with window object to detect window screen width like this

But I found that this way is not available when ssr because ssr rendering does not have window object.

Is there an alternative way I can get window size safely regardless of ssr?

解决方案

You can avoid calling your detection function in ssr by adding this code:

// make sure your function is being called in client side only
if (typeof window !== 'undefined') {
  // detect window screen width function
}

full example from your link:

import { useState, useEffect } from 'react';

// Usage
function App() {
  const size = useWindowSize();

  return (
    <div>
      {size.width}px / {size.height}px
    </div>
  );
}

// Hook
function useWindowSize() {
  // Initialize state with undefined width/height so server and client renders match
  // Learn more here: https://joshwcomeau.com/react/the-perils-of-rehydration/
  const [windowSize, setWindowSize] = useState({
    width: undefined,
    height: undefined,
  });

  useEffect(() => {
    // only execute all the code below in client side
    if (typeof window !== 'undefined') {
      // Handler to call on window resize
      function handleResize() {
        // Set window width/height to state
        setWindowSize({
          width: window.innerWidth,
          height: window.innerHeight,
        });
      }

      // Add event listener
      window.addEventListener("resize", handleResize);

      // Call handler right away so state gets updated with initial window size
      handleResize();

      // Remove event listener on cleanup
      return () => window.removeEventListener("resize", handleResize);
    }
  }, []); // Empty array ensures that effect is only run on mount
  return windowSize;
}

这篇关于如何使用反应钩子检测 Next.js SSR 中的窗口大小?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

1403页,肝出来的..

09-06 12:35