2017-08-25 81 views
4

我想實現一個裝載到我的反應成分,當背景圖像加載它應該顯示「加載」,然後一旦加載它應該顯示「加載」添加裝載機反應成分

我有我的componentwillMount()一個setTimeout()來測試裝載機按預期它確實

我竭力要了解它是如何知道的圖像加載時,並改變負荷狀態

是不是最好的使用加載器將圖像放入單獨的組件中,而不是將它放在Hello co上mponent?

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

你可以這樣說: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函數中跳過這個cckck:if (!timeoutOccured)

+0

這看起來不錯,你還可以用它來檢查一個組件是否正在加載? –

+0

@tomharrison,我不確定是否有方法檢查背景圖像是否正在加載,當您直接用'background:url(...)'設置它時。可能不會。 – mihai1990