Ajay Sivan
Ajay Sivan

Reputation: 2989

How to update progress and execute code after completion react-native

I'm really new to react-native. I'm trying to create a button with a progress indicator and want to execute some code on the progress completion. Somehow I have achieved the desired behaviour using the following code,

React Component

class ProgressButton extends Component {
  constructor() {
    super();
    this.state = {
      progress: 100,
    };
    this.progressTimer = null;
  }

  componentDidMount() {
    this.progressTimer = setInterval(() => {
      if(this.state.progress === 0) {
        clearInterval(this.progressTimer);
        // Run code on completion
      }
      this.setState({progress: this.state.progress - 1})
    }, 100)
  }

  render() {
    return (
      <button style={{backgroundPosition: this.state.progress + '%'}}>
        Hello
      </button>
    );
  }
}

CSS

button {
  font-size: 16px;
  width: 70px;
  height: 30px;
  border-radius: 4px;
  border: none;
  background-size: 200% 100%;
  background-image: linear-gradient(to right, black 50%, grey 50%);
  color: white;
  background-position: 100% 0;
}

But I'm not satisfied with this solution because,

  1. The progress animation is not smooth.
  2. I don't think using setInterval() is a good idea.

I have thought about doing the same with a CSS @keyframes animation and setTimeout() to execute the code on completion. But I'm not sure about it either because it may not be in sync.

Is there a better way to do this?

Upvotes: 2

Views: 426

Answers (2)

Yoel
Yoel

Reputation: 7985

Friend I shortened the way for you with animations

import { Animated} from 'react-native';

//in  constructor
 this.state = {
      progress: new Animated.Value(0);
    };

//in componentDidMount
Animated.timing(this.state.progress, {
    toValue: 100,//That you are interested
    duration: 500
}).start()

//in render
 const animator = this.state.progress.interpolate({
      inputRange: [0, 100],
      outputRange: ['1%', '100%'],
    });

//use animator in style
      <Animated.View  style={{height:animator}}/>

for you

import React, {Component} from 'react';
import {View, Text, Animated, Easing, TouchableHighlight} from 'react-native';

class App extends Component {
  constructor() {
    super();
    this.ani = new Animated.Value(0);
  }

  componentDidMount(): void {
    Animated.timing(this.ani, {
      toValue: 2,
      duration: 3000,
      easing: Easing.linear,
    }).start(() => {
      // Do something after animation (optional).
    });
  }

  render() {
    const animator = this.ani.interpolate({
      inputRange: [0, 1],
      outputRange: ['5%', '100%'],
    });

    return (
      <Animated.View
        style={{
          flex: 1,
          justifyContent: 'center',
        }}>
        <Animated.View
          style={{
            height: 60,
            backgroundColor: 'blue',
            width: animator,
          }}>
          <TouchableHighlight>
            <Text>press me</Text>
          </TouchableHighlight>
        </Animated.View>
      </Animated.View>
    );
  }
}

export default App;

Upvotes: 1

Damodhar
Damodhar

Reputation: 1317

for this, you need to create own custom component with animation

you can use this package or you need to follow this article

Upvotes: 1

Related Questions