directory
directory

Reputation: 3167

ReactJS transition for progress bar not working

I am just diving into ReactJS so I am quite a newbie in this Reactjs world. I have read the FB documentations and some tutorials on the internet and started my test project.

In my test project I am trying to include a progress bar for users to see their progress of filling down some forms across 3 pages. This part works all great till I wanted to add some transition magic to the process bar.

I've written the code below and I thought it would be the right way to archive my goal by pushing a prop from the parent to this child progressBar component for determining the percentage of the progress bar.

In my constructor I set the default width at 0 to update it by componentDidMount to a percentage which comes from the parent. I've managed to receive and set te style but the transition isn't working at all. I try to archive a fancy progress bar which runs from 0% width to the given width in percentage via the props.

My code look likes as follow:

ProgressBar component

import './style.scss';
import React from 'react';
import classnames from 'classnames';

class ProgressBar extends React.Component {

    constructor(props) {
    super(props);
    this.state = { progressionStyle : { } }
}
componentDidMount() {
    this.setState({
        progressionStyle : {
            width : this.props.progression,
            transition : 'all 1500ms ease'
        },
        scene1 : (this.props.scene1 == 'active') ? 'active' : (this.props.scene1 == 'done')   ? 'done' : '',
        scene2   : (this.props.scene2   == 'active') ? 'active' : (this.props.scene2 == 'done')     ? 'done' : '',
        scene3 : (this.props.scene3 == 'active') ? 'active' : (this.props.scene3 == 'done')   ? 'done' : '',
    });
}
/**
 *
 * Render
 * @return {JSX}
 */
render() {
    return (
        <div className="progress-bar">
            <div className="progress-bar__inner">

                <div className="progress-bar__progress">
                    <div className={classnames('progress-bar__progress-fill', this.props.active)} style={this.state.progressionStyle}></div>
                </div>

                <div id="scene1" className="progress-bar__element">
                    <i className={classnames('progress-bar__icon', this.state.scene1)}></i>
                    <span className="progress-bar__label">Scene 1</span>
                </div>

                <div id="scene2"  className="progress-bar__element">
                    <i className={classnames('progress-bar__icon', this.state.scene2)}></i>
                    <span className="progress-bar__label">Scene 2</span>
                </div>

                <div id="scene3" className="progress-bar__element">
                    <i className={classnames('progress-bar__icon', this.state.scene3)}></i>
                    <span className="progress-bar__label">Scene 3</span>
                </div>

            </div>
            </div>
        );
    }
}
export default ProgressBar;

Upvotes: 2

Views: 2250

Answers (2)

directory
directory

Reputation: 3167

To make this effect work, I've found out the solution was to wrap the style into a function and call via request animation frame via as fol

 componentDidMount() {
        requestAnimationFrame(()=> {
            this.showProgress();
        });
    }

    showProgress() {
        var style = { };
        style.width = this.props.progression;
        style.transition = 'all 1500ms ease-in';
        this.setState({style});
    }

https://stackoverflow.com/a/43779273/968898

Upvotes: 0

Shubham Khatri
Shubham Khatri

Reputation: 282080

You cannot set the nested state directly, you should be doing it like

componentDidMount() {
  var style = {...this.state.style}

  style.width = this.props.progression
  style.transition =   'all 500ms ease-in' 

  this.setState({style});
}

Also, you need to update your state in the componentWillReceiveProps function as you are updating state based on the props.

componentWillReceiveProps(nextProps) {
  var style = {...this.state.style}

  style.width = nextProps.progression
  style.transition = 'all 500ms ease-in' 

  this.setState({style});
}

Upvotes: 1

Related Questions