添加加载程序以响应组件

时间:2017-08-25 10:15:49

标签: javascript reactjs

我试图在我的反应组件上实现一个加载器,当加载背景图像时,它应该显示' loading'然后一旦加载它就应该显示加载'

我的setTimeout()上有componentwillMount()来测试加载程序是否按预期运行

我很难理解它是如何知道图像何时加载并改变加载状态

最好是将图像放入带有加载程序的单独组件中,而不是将它放在Hello组件上吗?

https://www.webpackbin.com/bins/-KsOEkf9ubvR6iz4bMxG

更新

我设法使用附加到图片的onload()方法让简单的图片加载器工作 - https://www.webpackbin.com/bins/-KsNpZPzveUoby1yriFo

Hello.js

 import React from 'react'
import Loader from './Loader'
import styled from 'styled-components'

const Card = styled.div`
  height: 400px;
  width:20%;
  background: url('https://www.planwallpaper.com/static/images/Light-Wood-Background-Wallpaper.jpg');
`
export default class Test extends React.Component {
  constructor() {
    super()
    this.state = { loading:true}
  }

  componentWillMount()
  {
     setTimeout(() => this.setState({loading: false}), 3000)
      console.log("componentDidMount");
  }

  render() {
    return (
      <div>
        <Card>
        <Loader loading={this.state.loading} />
        </Card>
      </div>
    )
  }
}

Loader.js

import React, { Component } from 'react'
import styled, { keyframes } from 'styled-components'
import { string } from 'prop-types'

const transition1 = keyframes`
  0%     { background: #F19939; }
  33.33% { background: #F8CA8F; }
  66.66% { background: #FBD8AE; }
  100%   { background: #F19939; }
`

const transition2 = keyframes`
  0%     { background: #FBD8AE; }
  33.33% { background: #F19939; }
  66.66% { background: #F8CA8F; }
  100%   { background: #FBD8AE; }
`

const transition3 = keyframes`
  0%     { background: #F8CA8F; }
  33.33% { background: #FBD8AE; }
  66.66% { background: #F19939; }
  100%   { background: #F8CA8F; }
`

const Box = styled.span`
  height: 12px;
  width: 12px;
  margin: 0 3px 0 3px;
  border-radius: 4px;
  animation: 0.4s ${transition1 } infinite;
`

const Box2 = styled(Box)`
  animation: 0.4s ${transition2 } infinite;
`

const Box3 = styled(Box)`
  animation: 0.4s ${transition3 } infinite;
`

const TextWrap = styled.div`
  display: flex;
  flex: 0 0 100%;
  justify-content: center;
  color: #fff;
`

const Para = styled.p`
  color: #fff
  padding: 19px 0 0 0;
`

const ParaLoaded = styled(Para)`
  color: #fff;
  padding: 22px 0 0 0;
`

export default class Loader extends Component {

  render() {
    return (
      <div >
        <div >

          <TextWrap>
            {
              this.props.loading
                ?
                  <Para>Loading...</Para>
                :
                  <ParaLoaded>Loaded</ParaLoaded>
            }
          </TextWrap>

        </div>
      </div>
    )
  }
}

1 个答案:

答案 0 :(得分:1)

你可以这样做:https://www.webpackbin.com/bins/-KsOJpBVfpazfXghJAaF

<强> LoadBackgroundImage.js

const LoadBackgroundImage = (component, imageUrl, seconds, success, failure) => {
  let timeoutOccured = false;
  const image = new Image();
  const timeout = setTimeout(() => {
    timeoutOccured = true;
    failure();
  }, seconds * 1000);

  image.onload = () => {
    clearTimeout(timeout);
    component.style.backgroundImage = `url('${imageUrl}')`;
    if (!timeoutOccured) success();
  };
  image.src = imageUrl;
};

export default LoadBackgroundImage;

<强> Hello.js

import React from 'react'
import Loader from './Loader'
import styled from 'styled-components'
import LoadBackgroundImage from './LoadBackgroundImage'

const Card = styled.div`
  height: 400px;
  width:20%;
`
export default class Hello extends React.Component {
  constructor() {
    super()
    this.state = { loading:true}
  }

  componentDidMount() {
    LoadBackgroundImage(
      this.card,
      'https://www.planwallpaper.com/static/images/Light-Wood-Background-Wallpaper.jpg',
      5,
      () => this.setState({ loading: false }),
      () => console.log('The image did not load in 5 seconds')
    );
  }

  render() {
    return (
      <div>
        <Card innerRef={card => this.card = card}>
          <Loader loading={this.state.loading} />
        </Card>
      </div>
    )
  }
}

在render()中,您使用innerRef获取对卡组件的引用并将其保存在this.card中。然后在componentDidMount中使用此引用和LoadBackgroundImage函数加载图像并监视它何时加载。如果以给定的秒数成功加载图像,则将调用回调,否则将调用失败回调。图像仍可在5秒后加载,但不会调用成功回调。如果你想要被调用,你可以在LoadBackgroundImage函数中跳过这个ckeck:if (!timeoutOccured)