reactjs 如何检测窗口宽度的变化?

hsvhsicv  于 2023-04-20  发布在  React
关注(0)|答案(3)|浏览(626)

根据窗口的宽度,我有不同的内容页面要应用。我使用以下条件:

{window.innerWidth > 575 ? <Big component> : <Little component>}

它工作得很好,但如果你不手动重新加载就减少页面,就不行了。
我试着在上面实现useEffect,但是我不知道如何通过widows.width的变化来触发它。请你帮帮我好吗?
这是我的代码:

const [windowSize, setWindowSize] = useState(window.innerWidth);

 useEffect(() => {
   setWindowSize(window.innerWidth);
 });

 return (
    ... 
      {windowSize > 575 ?  <Big component> : <Little component>}
    ...
);

先谢谢你了。

yks3o0rb

yks3o0rb1#

如果不注册事件侦听器,则无法实现innerWidth的更新。
下面是一个使用事件侦听器的方法:

const handleWindowResize = useCallback(event => {
    setWindowSize(window.innerWidth);
}, []);

useEffect(() => {
    window.addEventListener('resize', handleWindowResize);
    return () => {
        window.removeEventListener('resize', handleWindowResize);
    };
}, [handleWindowResize]);

您可以在useEffect钩子中添加和删除事件。
您可以使用useCallback钩子创建memoized处理程序。
这就是所谓的callback pattern
在这里,我们只是使用更新的innerWidth设置状态,最好使用callback pattern并仅在初始挂载时注册事件侦听器。
如果你在useEffect钩子中注册事件,listeners引用沿着词法作用域将被事件侦听器使用,但是一个新的函数将在每个新的render上创建一个更新的闭包,阻止处理程序访问更新的状态。
关于useCallbackhere的更多信息。

7kqas0il

7kqas0il2#

您可以使用window.onresize您可以检查here

function reportWindowSize() {
    console.log(window.innerHeight, window.innerWidth)
}

window.onresize = reportWindowSize;

你可以在钩子中使用window.addEventListener('resize', reportWindowSize)

const [windowWidth, setWindowWidth] = useState(window.innerWidth)
useEffect(() => {
    function reportWindowSize() {
        setWindowWidth(window.innerWidth)
        console.log(window.innerHeight, window.innerWidth)
    }
    // Trigger this function on resize
    window.addEventListener('resize', reportWindowSize)
    //  Cleanup for componentWillUnmount
    return () => window.removeEventListener('resize', reportWindowSize)
}, [])
wydwbb8l

wydwbb8l3#

使用Utsav和MDN文档去抖动,这是我为我的应用程序创建的自定义钩子

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

interface MediaObj {
  isMobile: boolean;
  isTablet: boolean;
  isLaptop: boolean;
  isDesktop: boolean;
};

//upper limit (BP) for each device. based off Bootstrap breakpoints
const mobileBP = 768; //sm
const tabletBP = 992;  //md 
const laptopBP = 1200  //lg
const dekstopBP = 1400; //xlg

const defaultValues= {
  isMobile: window.innerWidth <= mobileBP ? true : false,
  isTablet: (window.innerWidth > mobileBP && window.innerWidth <= tabletBP) ? true : false,
  isLaptop: (window.innerWidth > tabletBP && window.innerWidth <= laptopBP) ? true : false,
  isDesktop: (window.innerWidth > laptopBP) ? true : false,
}

const useDetectResize = () => {
  const [mediaType, setMediaType] = useState<MediaObj>(defaultValues);
  const [windowDimensions, setWindowDimensions] = useState<{w:number, h:number}>({w: window.innerWidth, h: window.innerHeight});
  let timeout = false;

  //register callback so our function isn't instantiated on each re-render.
  const handleWindowResize = useCallback((timeout:any) => {
    // clear the timeout
    clearTimeout(timeout);
    // debounce getDimensions function ever N ms
    timeout = setTimeout(getDimensions, 1000);

    //store width/height and mediaState 
    function getDimensions(){
      let width = window.innerWidth;
      let height = window.innerHeight;
      setWindowDimensions(currState => currState = {w:width, h: height});
      console.log('Width Saved!: ', width);

      let mediaTypes = {
        isMobile: window.innerWidth <= mobileBP ? true : false,
        isTablet: (window.innerWidth > mobileBP && window.innerWidth <= tabletBP) ? true : false,
        isLaptop: (window.innerWidth > tabletBP && window.innerWidth <= laptopBP) ? true : false,
        isDesktop: (window.innerWidth > laptopBP) ? true : false,
      }

      setMediaType(currState => currState = mediaTypes);
    }

}, []); 

  useEffect(() => {
    // window.resize event listener will call handleWindowResize() whenever screen width is adjusted.
    window.addEventListener('resize', handleWindowResize);

    return () => window.removeEventListener('resize', handleWindowResize);
  },[])
  
  return{
    isMobile: mediaType.isMobile,
    isTablet: mediaType.isTablet,
    isLaptop: mediaType.isLaptop,
    isDesktop: mediaType.isDesktop,
    windowDimensions
  }
}

export default useDetectResize;

然后在组件中调用它

const { windowDimensions, isMobile, isTablet, isLaptop, isDesktop } = useDetectResize();

相关问题