Reputation: 3167
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
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
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