使用onLoad方法在React中加载图像?

Moe*_*Joe 6 reactjs

我的目标是让我的图库图像在加载时呈现.
在线查看,我已经了解了这种onLoad方法.
这是我试图利用的,这个想法是preloader.gif在图像加载之前渲染并简单地用加载的图像替换图像src.

就像现在(下图)一样,如果我没有使用这种onLoad方法,图像看起来像往常一样加载,所以在加载图像之前,根本没有图像被渲染.

我究竟做错了什么?

我已经删除了代码以使问题更容易阅读.

import React from 'react';
import ReactDOM from 'react-dom';

import preloaderImage from '../../../img/site/preloader.gif';

class WorksPage extends React.Component {

  constructor(){
    super();
  }

  imageLoadHandler(image,e) {
    e.target.src = image;
  }


  render() {

    const listWork = this.props.array.map((item,index)=> {
      return(
        <li key={item.id}>
          <div>
            <img src={preloaderImage} onLoad={this.imageLoadHandler.bind(this,item.image)}/>
          </div>
        </li>
      )
    });

    return(
      <li>
        <div>
          <ul>
            {listWork}
          </ul>  
        </div>  
      </li>
    )
  }
}

module.exports = WorksPage;
Run Code Online (Sandbox Code Playgroud)

GPr*_*ost 11

以下是preloader未呈现图像的原因:

  1. preloaderImage 负载
  2. 当它被加载时imageLoadHandler触发器和src属性被更改为主imagesrc(因此preloaderImage即使现在已加载也不会呈现)
  3. 现在主图像加载
  4. 当它被加载时,它被渲染

你应该如何正确地做到:

  1. 如果你编写React app,你应该这样做React方式:

    • state在其constructor方法中将图像设置为组件.你需要这样做是因为你要改变渲染图像的方式(在React中你通过改变组件来实现渲染更改,props或者state在你的情况下它应该是这样state).但请注意,您应该src为列表中的每个图像设置属性preloaderImage(在下面的示例中我使用的是object destructuring语法).

      constructor() {
        super();
        this.state = {
          images: this.props.images.map(image => ({
            ...image,
            src: preloaderImage
          }))
        }
      }
      
      Run Code Online (Sandbox Code Playgroud)
    • 现在在render方法中创建像这样的图像列表(注意,onLoad这里不需要处理程序):

      const listWork = this.state.images.map(image => (
        <li key={image.id}>
          <div>
            <img src={image.src} />
          </div>
        </li>
      ));
      
      Run Code Online (Sandbox Code Playgroud)
  2. componentWillMount方法开始加载主图像src动态使用香草JS(你可以阅读一下文章here).因为它们被加载调用setState方法来更新图像src属性:

    componentWillMount() {
      this.state.images.forEach((image, index) => {
        const {src} = this.props.images[index] // get image primary src
        const primaryImage = new Image() // create an image object programmatically
        primaryImage.onload = () => { // use arrow function here
          console.log(`image #${index + 1} is loaded!`)
          const images = [...this.state.images] // copy images array from state
          images[index].src = src // adjust loaded image src
          this.setState({
            images
          })
        }
        primaryImage.src = src // do it after you set onload handler
      })
    }
    
    Run Code Online (Sandbox Code Playgroud)

    setState使用更改的images数组调用之后,React将使用正确的src路径自动重新渲染您的图像.


使用CSS更优雅的方式:

<img />您可以使用<div />带有background-imagecss属性的标记而不是标记.在那里你可以简单地设置你的后备(预加载)图像:

background-image: url('path/to/primary-image'), url('path/to/preload-image');
Run Code Online (Sandbox Code Playgroud)

您可以使用style属性动态设置路径(在您的render方法中):

const listWork = this.props.images.map(image => {
  const imageStyle = {
    backgroundImage: `url(${image.src}), url(${preloaderImage});`
  }
  return (
    <li key={image.id}>
      <div>
        <div style={imageStyle} />
      </div>
    </li>
  )
})
Run Code Online (Sandbox Code Playgroud)

只是不要忘记设置heightwidth<div />.