繁体   English   中英

使 function 内部 useEffect 在 mount 上运行?

[英]Make function inside useEffect run on mount?

Main Function内部,我在 useEffect 中有一个useEffect updateResize - 它在调整大小时有效,但我希望它在加载时也能运行 - 这样当您在移动设备上加载网站时,它会相应地更新。

import React, {useState, useEffect} from 'react'
import Lightbox from "./lightbox"
import portData from "./portData"
import PortItem from "./portItem"
import ArrowLH from "../../files/images/ArrowLeftHighlight.svg"
import ArrowL from "../../files/images/ArrowLeft.svg"
import ArrowRH from "../../files/images/ArrowRightHighlight.svg"
import ArrowR from "../../files/images/ArrowRight.svg"
import "./portfolio.css"

// Window Size Function
function useWindowSize() {
    const [windowSize, setWindowSize] = useState({
      width: undefined,
      height: undefined,
    });
  
    useEffect(() => {
      function handleResize() {
        setWindowSize({
          width: window.innerWidth,
          height: window.innerHeight,
        });
      }
      window.addEventListener("resize", handleResize);
    
      handleResize();
      
      return () => window.removeEventListener("resize", handleResize);
    }, []);
  
    return windowSize;
  }

// Main Function
const  PortfolioPage = () => {
    const size = useWindowSize();
    const [arrowside, setArrowside] = useState(null);

    const portItems = portData.map(item => <PortItem key={item.id} pitem={item} click={handleClick}/>);
    portItems.reverse();

    const [{portLength, skipLength, startPort}, setPort] = useState({
        portLength: 8,
        skipLength: 4,
        startPort: 0,
      });
      
    const [{lightboxActive, lightboxId}, setLb] = useState({
        lightboxActive: false,
        lightboxId: null,
    });

    // Update Port Length
    useEffect(() => {
        const updateResize = () => {
            console.log(size.width)
            if(size.width <= 750 && portLength !== 2){
                setPort(c => ({...c, portLength: 2, skipLength: 2}))
            } 
            else if (size.width <= 950 && size.width >= 650 && portLength !== 4){
                setPort(c => ({...c, portLength: 4, skipLength: 4}))
            }else if (size.width <= 1250 && size.width >= 950 && portLength !== 6){
                setPort(c => ({...c, portLength: 6}))
            } else if (size.width >= 1250 && portLength !== 8){
                setPort(c => ({...c, portLength: 8}))
            }
        }
        return () => {
            updateResize();
        }
    }, [size.width, portLength])
    
    //Mouse Handling
    function onHover(side, sit) {
        if(sit === "enter"){
            setArrowside(side)
        } else setArrowside(null)
    }

    function handleClick(id) {
        if(arrowside !== null){
            if(arrowside === 'left' && startPort !== 0){
                setPort(c => ({...c, startPort: startPort - skipLength}))
            } else if(arrowside === 'right' && startPort + portLength < portData.length){
                setPort(c => ({...c, startPort: startPort + skipLength}))
            }

        } else if (!lightboxActive){
            setLb(c => ({lightboxId: id,  lightboxActive: true}))
        } else if (lightboxId !== null){
            setLb(c => ({lightboxActive: false}))
        }
    }
    
    return(
        <div>
                <Lightbox  pitem={portData[lightboxId]} lightbox={lightboxActive} click={handleClick}/>
                <div className="portfolio-container">
                    <div className="arrow-container">
                        <div 
                        className="arrow" 
                        id="ArrowLeft" 
                        onMouseEnter={()=>onHover("left", "enter")}
                        onMouseLeave={()=>onHover("left", "leave")}
                        onClick={handleClick}
                        >
                            <img src={ArrowL} alt="Arrow Left" className={arrowside === "left" ? null : "active"}/>
                            <img src={ArrowLH} alt="Arrow Left Highlighted" className={arrowside === "left" ? "active" : null}/>
                        </div>
                    </div>
                    <div className="portfolio-item-container">
                        {portItems.slice(startPort, startPort + portLength)}
                    </div>
                    <div className="arrow-container">
                        <div 
                        className="arrow" 
                        id="ArrowRight"
                        onMouseEnter={()=>onHover("right", "enter")}
                        onMouseLeave={()=>onHover("right", "leave")}
                        onClick={handleClick}
                        >
                            <img src={ArrowR} alt="Arrow Right" className={arrowside === "right" ? null : "active"}/>
                            <img src={ArrowRH} alt="Arrow Right Highlighted" className={arrowside === "right" ? "active" : null}/>
                        </div>
                    </div>
                </div>
            </div>
    )
}

export default PortfolioPage

应该这样做,

// Window Size Function
function useWindowSize() 
{
    const [windowSize, setWindowSize] = useState({
      width: undefined,
      height: undefined,
    });

   function handleResize() {
        setWindowSize({
          width: window.innerWidth,
          height: window.innerHeight,
        });
      }
  
    useEffect(() => {
      handleResize();

      window.addEventListener("resize", handleResize);
    
      return () => window.removeEventListener("resize", handleResize);
    }, []);
  
    return windowSize;
  }

尝试用useEffect替换useLayoutEffect 当考虑到在浏览器绘制过程之前需要改变 DOM 时, useLayoutEffect

https://reactjs.org/docs/hooks-reference.html#uselayouteffect

暂无
暂无

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

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