Adding a loader to a reaction component

I am trying to implement a bootloader for my reaction component, when the background image is loading, it should display “loading”, and then after loading it it should display “loaded”

I have setTimeout()on mine componentwillMount()to check that the bootloader is functioning as expected, what it does

I am trying to understand how he knows when the image is loading, and change the loading status

Is it better to put the image in a separate component with the loader, and not on the Hello component?

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

Update

I managed to get a simple image downloader using the method onload()attached to the image - 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>
    )
  }
}
+4
source share
1 answer

You can do it like this: 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 . componentDidMount LoadBackgroundImage . , , . - 5 , . , , ckeck: if (!timeoutOccured) LoadBackgroundImage.

+1

Source: https://habr.com/ru/post/1684454/


All Articles