【问题标题】:How do i load all images before rendering the page?如何在渲染页面之前加载所有图像?
【发布时间】:2020-09-18 05:28:05
【问题描述】:

所以我有一个可以工作的预加载器,只是我的图像组件本身存在一些问题。 在我的理论中,我下面的图像组件应该在第一次渲染后获取我在项目中使用的所有图像标签。

然后当图像事件 onLoad 被触发时,它应该更新一个状态为 didLoad 并将其设置为 true。当页面因为更新状态而再次重新渲染时,它应该检查 didLoad 是否为 true,如果为 true,则应在条件内执行一次 useEffect 并将加载量加 1。

然后我检查图像是否高于 0,并且图像等于加载的图像然后删除预加载器。

显然出了点问题,因为我无法让它工作,它需要同时处理所有图像,而不是一次处理一个,因为它不是图像本身的延迟加载,而是整个页面的预加载器。

Ignore preload: false 用于当预加载器被移除时,它应该播放页面动画。

/** @jsx jsx */
import React, { useContext, useEffect, useState } from "react";
import { css, jsx } from "@emotion/core";
import preloadContext from "../../context/preload.context";

const Img = ({ src, alt }) => {
  const [didLoad, setLoad] = useState(false);
  const [preload, setPreload] = useContext(preloadContext);
  const imgStyle = css`
    width: 100%;
    height: 100%;
    display: block;
    object-fit: cover;
  `;

  useEffect(() => {
    setPreload({
      amount: preload.amount++,
      preload: preload.preload,
      isLoaded: preload.isLoaded,
    });
  }, []);

  if (didLoad === true) {
    useEffect(() => {
      setPreload({
        amount: preload.amount,
        preload: preload.preload,
        isLoaded: preload.isLoaded++,
      });
    }, []);
  }

  return (
    <img
      src={src}
      onLoad={(e) => {
        setLoad(true);
      }}
      css={imgStyle}
      alt={alt}
      onDragStart={(e) => e.preventDefault()}
    />
  );
};

export default Img;

【问题讨论】:

    标签: reactjs react-hooks use-effect


    【解决方案1】:

    答案是你可以你不能

    我们可以:如果您尝试将某个组件的渲染保持到&lt;img /&gt;(加载此组件的外部)

    我们不能:如果您尝试跟踪未呈现组件内部的&lt;img /&gt; 的加载。在这种情况下,图像在我们渲染它的父组件之前不会加载。


    对于第一个选项,您可以这样做:

    constructor(props) {
        super(props);
        this.state = { loaded: 0 };
        this.handleImageLoaded = this.handleImageLoaded.bind(this);
        this.image = React.createRef();
    }
    
    componentDidMount() {
        const img = this.image.current;
        if (img && img.complete) {
            this.handleImageLoaded(10); // 100 / Number of images to track
        }
    }
    
    handleImageLoaded(loadIncrement) {
        if (!this.state.loaded)
            this.setState({ loaded: loadIncrement });
    } 
    
    render() {
        return (
            <div>
                 <img src='image.jpg' ref={this.image} onLoad={this.handleImageLoaded} />
                 {this.state.loaded >= 100 && <MyComponent />}
            </div>
        );
    }
    

    如评论中所述,您必须将 100 除以您希望跟踪的图像数量,然后加载一个图像,它将加载百分比添加到父状态。一个加载状态达到 100 或以上会渲染 &lt;MyComponent /&gt;

    【讨论】:

    • 组件渲染完毕,preloader只是一个覆盖整个屏幕直到满足条件的覆盖层
    • 这不是最好的解决方案吗?它不需要您事先知道页面上的图像数量吗,我宁愿想要一个动态解决方案,并且可以与 useContext 一起使用,因为我正在使用它与 App 共享状态。
    猜你喜欢
    • 2016-10-27
    • 1970-01-01
    • 1970-01-01
    • 2018-07-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-27
    • 1970-01-01
    相关资源
    最近更新 更多