Automatically calculates the width and height of the React component

Github address: github.com/niexq/react… Welcome to Star

🏠 Home page preview

📦 installation

  yarn add @oyyds/react-auto-sizer  # or npm i @oyyds/react-auto-sizer -S
Copy the code

🔨 use

import AutoSizer from '@oyyds/react-auto-sizer';

const AutoSizeComponent = () = > {
  return (
    <div>
      <AutoSizer>
        {({ width, height }) => (
          <div
            style={{
              width.height,}} >Content area</div>
        )}
      </AutoSizer>
    </div>
  );
};
Copy the code

🧩 Service Scenarios

Nowadays, most business scenarios need to be compatible with big data, such as big data tables, big data trees, big data drop-down boxes, etc. All big data components need to specify the width and height. Most actual business interfaces need to calculate the width and height in real time, and React-Auto-sizer is used to automatically calculate the width and height.

🧑💻 coding implementation

At the beginning, I studied binding REsize on Windows, but because resize will have performance problems when the form changes, there will be jitter in some extreme pixels.

ResizeObserver, the interface can listen for changes in an Element’s content area or SVGElement’s bounding box. The content area needs to subtract the padding. From MDN

ResizeObserver The Chosen Child, using React Hook useEffect, the core code is as follows:


const updateState = useCallback(
    (newWidth: number, newHeight: number, entry: ResizeObserverEntry) = > {
      // omit updating state
      // Call back width, height
      props.onResize({ width: newWidth, height: newHeight }, entry);
    },
    [childParams, disableHeight, disableWidth, onResize],
  );

const observer = useMemo(
    () = >
      new ResizeObserver((entries: ResizeObserverEntry[]) = > {
        for (const entry of entries) {
          const contentRect = entry.contentRect;
          const width = Math.trunc(contentRect? .width ||0);
          const height = Math.trunc(contentRect? .height ||0);
          updateState(width, height, entry);
        }
      }),
    [updateState],
  );
  
useEffect(() = > {
    if(! _autoSizerRef? .current? .parentNode) {throw new Error('Not Found AutoSizer parentNode'); } observer.observe(_autoSizerRef? .current? .parentNodeas Element);
    return () = > {
      observer.disconnect();
    };
  }, [observer]);
Copy the code

Key points:

observer.observe(_autoSizerRef? .current? .parentNode as Element), listening on the parent DOM node

ContentRect: ResizeObserverEntry Returns a contentRect with a DOMRectReadOnly read-only property that contains the object of the new size to observe the element, with properties:

{
  "x": 0."y": 0."width": 300."height": 200."top": 0."right": 300."bottom": 200."left": 0
}
Copy the code

ContentRect returns the content box, that is, the size of the content area (please refer to Zhang Xinxu’s Introduction to ResizeObserver for details)

So contentRect.width and contentrect. height are the final width we need

🐳 Source of inspiration

React-virtualized – Auto-Sizer ResizeObserver JS API ResizeObserver for DOM size change detection

🐠 Past hydrology

No recursion to generate an infinite hierarchy of trees

Deployment based on qiankun micro front-end combat