How to get a react component's size (height/width) before render?

前端 未结 6 1212
天命终不由人
天命终不由人 2020-12-03 00:22

I have a react component that needs to know its dimensions ahead of time, before it renders itself.

When I\'d make a widget in jquery I could just <

6条回答
  •  南方客
    南方客 (楼主)
    2020-12-03 01:21

    There's an unexpected "gotcha" with @shane's approach for handling window resizing: The functional component adds a new event listener on every re-render, and never removes an event listener, so the number of event listeners grows exponentially with each resize. You can see that by logging each call to window.addEventListener:

    window.addEventListener("resize", () => {
      console.log(`Resize: ${dimensions.width} x ${dimensions.height}`);
      clearInterval(movement_timer);
      movement_timer = setTimeout(test_dimensions, RESET_TIMEOUT);
    });
    

    This could be fixed by using an event cleanup pattern. Here's some code that's a blend of @shane's code and this tutorial, with the resizing logic in a custom hook:

    /* eslint-disable react-hooks/exhaustive-deps */
    import React, { useState, useEffect, useLayoutEffect, useRef } from "react";
    
    // Usage
    function App() {
      const targetRef = useRef();
      const size = useDimensions(targetRef);
    
      return (
        

    {size.width}

    {size.height}

    ); } // Hook function useDimensions(targetRef) { const getDimensions = () => { return { width: targetRef.current ? targetRef.current.offsetWidth : 0, height: targetRef.current ? targetRef.current.offsetHeight : 0 }; }; const [dimensions, setDimensions] = useState(getDimensions); const handleResize = () => { setDimensions(getDimensions()); }; useEffect(() => { window.addEventListener("resize", handleResize); return () => window.removeEventListener("resize", handleResize); }, []); useLayoutEffect(() => { handleResize(); }, []); return dimensions; } export default App;

    There's a working example here.

    This code doesn't use a timer, for simplicity, but that approach is further discussed in the linked tutorial.

提交回复
热议问题