在反应中调整事件大小

Resize event in react

我想在 react.js 中监听 window 调整大小事件。我尝试使用 window.addEventListener 但多次触发回调。有没有一种方法可以让回调只运行一次,或者只是一种更面向反应的方式(可能是一个钩子)来实现这个?

    const resizeQuery = () => {
    console.log("check");
    if (desktop) setnumberOfShownImages(4);
    else if (tablet) setnumberOfShownImages(3);
    else if (mobile) setnumberOfShownImages(1);
  };

    window.addEventListener('resize',resizeQuery);

完整组件代码:

function ImageSlider(props) {
  const [numberOfShownImages, setnumberOfShownImages] = useState(props.numberOfShownImages);
  const currentIndex = 0;
  const array = [
                <PrimaryCard imageHeight = "200" imageAlt = "Fox" imagePath = {fox} header = "Fox" description = "This is a 1"/>,
                <PrimaryCard imageHeight = "200" imageAlt = "Fox" imagePath = {fox} header = "Fox" description = "This is a 2"/>,
                <PrimaryCard imageHeight = "200" imageAlt = "Fox" imagePath = {fox} header = "Fox" description = "This is a 3"/>,
                <PrimaryCard imageHeight = "200" imageAlt = "Fox" imagePath = {fox} header = "Fox" description = "This is a 4"/>,
                <PrimaryCard imageHeight = "200" imageAlt = "Fox" imagePath = {fox} header = "Fox" description = "This is a 5"/>,
                <PrimaryCard imageHeight = "200" imageAlt = "Fox" imagePath = {fox} header = "Fox" description = "This is a 6"/>,
                <PrimaryCard imageHeight = "200" imageAlt = "Fox" imagePath = {fox} header = "Fox" description = "This is a 7"/>,
  ];
  const classes = useStyles();

  const theme = useTheme();
  const desktop = useMediaQuery(theme.breakpoints.up("lg"));
  const tablet = useMediaQuery(theme.breakpoints.up("sm"));
  const mobile = useMediaQuery(theme.breakpoints.up("xs"));

  const resizeQuery = () => {
    console.log("Mahad0");
    if (desktop) setnumberOfShownImages(4);
    else if (tablet) setnumberOfShownImages(3);
    else if (mobile) setnumberOfShownImages(1);
  };

    window.addEventListener('resize',resizeQuery);

  return (
    <div className={classes.paper}>
        <IconButton aria-label="delete" color="primary">
            <ArrowBackIosNewIcon fontSize='large' color='secondary'/>
        </IconButton>
        {
            array.slice(currentIndex, numberOfShownImages)
        }
        <IconButton aria-label="delete" color="primary">
            <ArrowForwardIosIcon fontSize='large' color='secondary'/>
        </IconButton>
    </div>
  )
}

使用 windowsize 钩子

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(() => {
    // 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;
}