React.js学习-图片懒加载(高阶组件实现)

2020-05-12 23:03:542020-10-16 17:33:00

懒加载实现方式

HTML5新API:new IntersectionObserver(callback)

观察一个元素后,当元素出现在视口内,会触发回调

其他实现方式

代码实现

// MLazyLoad.tsx

import React, { useEffect, useRef, useState } from 'react';
import { clone } from 'ramda';


interface PropsI {
  element: () => JSX.Element,
}

const LazyLoad: React.FC<PropsI> = (props: PropsI) => {
  const [Element, setElement] = useState<JSX.Element>(props.element());
  const elementRef = useRef<HTMLDivElement>(null);
  useEffect(() => {
    (async () => {
      if (!elementRef || !elementRef.current) return;
      const observer = new IntersectionObserver((changes) => {
        changes.forEach((change) => {
          if (change.isIntersecting) {
            const Com = clone(Element);
            Com.props.src = Com.props['data-src'];
            Reflect.deleteProperty(Com.props, 'data-src');
            setElement(Com);
            observer.unobserve(change.target);
          }
        });
      });
      observer.observe(elementRef.current);
    })();
  }, []);
  return (
    <div ref={elementRef}>
      {
        Element
      }
    </div>
  );
};

export default function (element: () => JSX.Element) {
  return (
    <LazyLoad element={element} />
  );
}

使用方式

const ImageNode = () => <img className={style.itemImg} data-src="xxx" alt="" />;

<div>
    {
        lazyLoad(ImageNode)
    }
</div>

效果

lazyload