繁体   English   中英

NextJS:如何让这个组件在页面加载时显示宽度?

[英]NextJS: How do I get this component to display width on page load?

当运行以下获取浏览器屏幕宽度的代码时,出现此错误:

ReferenceError: window 未定义

注释掉的代码有效,使用 0 作为默认值,但在浏览器宽度更改时会正确更新。

我要么得到 window 未定义错误,要么将默认数字传递给 state,这会在页面加载时显示不正确的宽度。

如何在页面加载时定义 window.innerWidth?

import React, { useState, useEffect } from "react";

const WindowTracker = () => {
    const [show, setShow] = useState(true);
    // const [windowWidth, setWindowWidth] = useState(0);
    const [windowWidth, setWindowWidth] = useState(window.innerWidth);

    const triggerToggle = () => {
        setShow(!show);
    };

    useEffect(() => {
        function watchWidth() {
            setWindowWidth(window.innerWidth);
        }

        window.addEventListener("resize", watchWidth);

        return function () {
            window.removeEventListener("resize", watchWidth);
        };
    }, []);

    return (
        <div>
            <button onClick={triggerToggle}>Toggle WindowTracker</button>
            {show && <h1>Window width: {windowWidth}px</h1>}
        </div>
    );
    // }
};

export default WindowTracker;

谢谢!

使用这个钩子:

 const [windowWidth, setWindowWidth] = useState(); useEffect(() => { setWindowWidth(window.innerWidth) }, [window.innerWidth])

发生这种情况是因为在 nextjs 在 window 服务器上执行的预渲染中它尚未定义,我通过添加一个 if 在我的代码中解决了这个问题,这是它看起来如何的示例代码

import React, { useState, useEffect } from "react";

const WindowTracker = () => {
  const [show, setShow] = useState(true);
  // const [windowWidth, setWindowWidth] = useState(0);
  const [windowWidth, setWindowWidth] = useState(typeof window !== "undefined" ? window.innerWidth : 0);

  const triggerToggle = () => {
    setShow(!show);
  };

  useEffect(() => {
    if (typeof window !== "undefined") {
      function watchWidth() {
        setWindowWidth(window.innerWidth);
      }

      window.addEventListener("resize", watchWidth);

      return function () {
        window.removeEventListener("resize", watchWidth);
      };
    }
  }, []);

  return (
    <div>
      <button onClick={triggerToggle}>Toggle WindowTracker</button>
      {show && <h1>Window width: {windowWidth}px</h1>}
    </div>
  );
  // }
};

export default WindowTracker;

您应该在组件挂载时触发setWindowWidth

const isClientSide = () => typeof window !== 'undefined';

const getWindowSize = () => {
    if (isClientSide()) return window.innerWidth
    return 0
}

const WindowTracker = () => {
    const [show, setShow] = useState(true);
    const [windowWidth, setWindowWidth] = useState(getWindowSize());

    const triggerToggle = () => {
        setShow(!show);
    };

    useEffect(() => {
        function watchWidth() {
            setWindowWidth(window.innerWidth);
        }

        window.addEventListener("resize", watchWidth);
        setWindowSize(getWindowSize());  <=== This should set the right width
        return function () {
            window.removeEventListener("resize", watchWidth);
        };
    }, []);

    return (
        <div>
            <button onClick={triggerToggle}>Toggle WindowTracker</button>
            {show && <h1>Window width: {windowWidth}px</h1>}
        </div>
    );
};

export default WindowTracker;

useEffect挂钩中,您还可以调用setWindowWidth(window.innerWidth); at 将 state 和 window.innerWidth 设置为在 pageLoad 上具有所需的宽度。

const [windowWidth, setWindowWidth] = useState(0);

useEffect(() => {
        function watchWidth() {
            setWindowWidth(window.innerWidth);
        }

        window.addEventListener("resize", watchWidth);

        //  Call right away so state gets updated with initial window size
        setWindowWidth(window.innerWidth);

        return function () {
            window.removeEventListener("resize", watchWidth);
        };
    }, []);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM