Implementation code of React countdown function decoupling general purpose
- 2021-08-21 19:35:38
- OfStack
Requirement analysis
Demand
In a certain page need to have a countdown function, countdown 5 s, 5s clock jump to the new interface
Analysis
The first is to realize the countdown function The second is to realize the function of changing the number of countdown seconds on the page after every countdown of 1 s Finally, it realizes the function of jumping to the specified page after the countdown is completedFirst edition practice
Code
let waitTime = 5
class DemoPage extends React.Component {
constructor(props) {
super(props);
this.state = {
time: '',
};
}
componentDidMount = () => {
this.countDown();
};
countDown = () => {
if (waitTime > 0) {
waitTime--;
this.setState({
time:waitTime
})
} else {
history.push('/Login')
return;
}
setTimeout(() => {
this.countDown();
}, 1000);
}
render() {
todoInfo = this.state.time + ' Jump to the login interface after seconds ';
return (
<div>
todoInfo
</div>
);
}
}
export default DemoPage;
Problem analysis
Time is set to a global variable, bad practice,
Inconvenient to modify Difficult to read and understand The value of a global variable is extremely unsafe and may be modified by any programImproved version
Code
class DemoPage extends React.Component {
constructor(props) {
super(props);
this.state = {
time: '',
};
}
componentDidMount = () => {
this.countDown(5);// The countdown time can be adjusted at will, and the readability is strong
};
countDown = (waitTime) => {
if (waitTime > 0) {
waitTime--;
this.setState({
time:waitTime
})
} else {
history.push('/Login')
return;
}
setTimeout(() => {
this.countDown(waitTime);
}, 1000);
}
render() {
todoInfo = this.state.time + ' Jump to the login interface after seconds ';
return (
<div>
todoInfo
</div>
);
}
}
export default DemoPage;
After improvement, the time is put into countDown as a parameter, which is convenient to set the countdown time at will
Step 1 to analyze the problem:
The above practice,
The operation of setState can only be written in this component, and it is tightly coupled with this component at 1, so it is impossible to realize multi-component reuse history. push ('/Login') can only be used in the framework of umi, which is tightly coupled with the framework and cannot be used universallyTake one step to improve
To meet the needs of this problem, you can expand the business scenario to:
Countdown function Need to do something in the countdowndoSomethingDuringCountDown()
Need to do sth after the countdown is over
doSomethingAfterCountDown()
In this way, the countdown function can be used more flexibly.
Program
Pass the function as an argument to the countDown () method
Will
doSomethingDuringCountDown()
And
doSomethingAfterCountDown()
As a parameter to the countDown method,
Specific methods to achieve, according to the needs of their own pages to achieve.
Code
//utils.js
export countDown = (waitTime,doSomethingDuringCountDown,doSomethingAfterCountDown){
if (waitTime > 0) {
waitTime--;
if(doSomethingDuringCountDown){
doSomethingDuringCountDown()
}
} else {
if(doSomethingAfterCountDown){
doSomethingAfterCountDown()
}
return;
}
setTimeout(() => {
countDown(waitTime,doSomethingDuringCountDown,doSomethingAfterCountDown);
}, 1000);
}
Instances
//DemoPage.jsx
import { countDown } from 'utils.js'
class DemoPage extends React.Component {
constructor(props) {
super(props);
this.state = {
time: '',
};
}
componentDidMount = () => {
countDown(5,this.waitTimeStateChange,this.linkTo);
}
waitTimeStateChange = (time) => {
this.setState({
time: time,
})
}
linkTo = () => {
history.push(ToBeReviewedShowData.linkUrl)
}
render() {
todoInfo = this.state.time + ' Jump to the login interface after seconds '
return (
<div>
todoInfo
</div>
)
}
}
export default DemoPage
Summarize