Comments (11)
I was able to mitigate this error with a timeout:
Method
countDownFinished() {
setTimeout(() => {
this.setState({ showCountDown: false })
}, 100)
}
Component
{this.state.showCountDown === true &&
<CountDown size={28} until={15} onFinish={() => this.countDownFinished()}
timeToShow={['M', 'S']} timeLabels={{ m: null, s: null }} showSeparator />
}
from react-native-countdown-component.
After I upgrade to latest version the problem not show anymore. (I used 2.2.0 before)
Thanks for your support.
from react-native-countdown-component.
Try this
its wroked for me
just update in your component index.js
componentDidMount() {
AppState.addEventListener('change', this._handleAppStateChange); <--- Remove this
this.eventListener = AppState.addEventListener('change', this._handleAppStateChange); <--- Add this
}
componentWillUnmount() {
clearInterval(this.timer);
AppState.removeEventListener('change', this._handleAppStateChange); <--- Remove this
this.eventListener.remove(); <--- and add this
}
from react-native-countdown-component.
Add componentwill Unmount method in your js file .
ComponentwillUnmount(){
this.setState({})
}
After state ,
Then prob will be solved.
from react-native-countdown-component.
Add componentwill Unmount method in your js file .
ComponentwillUnmount(){
this.setState({})
}After state ,
Then prob will be solved.
I'm having a similar problem. This solution didn't work for me. Do you/does anyone else have another suggestion?
from react-native-countdown-component.
Warning: Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method.
Above Error or warning show when the timer is finished after time.
<CountDown
until = {5}
size={14}
onFinish={() => { (this.state.otp_resend) ? console.log("Sorry No timer") : this.showresendbutton() }}
digitStyle={{backgroundColor: 'transparent',textAlign: 'left',color: '#cccccc', margin:0,height:10}}
digitTxtStyle={{color: '#000000',textAlign: 'left', margin:0}}
timeToShow={['M', 'S']}
timeLabels={{m: '', s: ''}}
style={{ textAlign: 'left', margin:0, }}
showSeparator
/>showresendbutton= async () => {
this.setState({ otp_resend: true })
}
I found a solution that worked for me. While the timer clears the interval and removes the event listener in the componentWillUnmount lifecycle method, it didn't have anything to handle async requests on unmounted components. I edited the index.js file in the react-native-countdown-component folder. I followed a guide from here when editing it.
Essentially add a class field to hold the lifecycle state of the component. Ex:
`class CountDown extends React.Component {
_isMounted = false;
static propTypes = {
id: PropTypes.string,
digitStyle: PropTypes.object,
digitTxtStyle: PropTypes.object,
timeLabelStyle: PropTypes.object,
separatorStyle: PropTypes.object,
timeToShow: PropTypes.array,
showSeparator: PropTypes.bool,
size: PropTypes.number,
until: PropTypes.number,
onChange: PropTypes.func,
onPress: PropTypes.func,
onFinish: PropTypes.func,
};
state = {
until: Math.max(this.props.until, 0),
lastUntil: null,
wentBackgroundAt: null,
};
constructor(props) {
super(props);
this.timer = setInterval(this.updateTimer, 1000);
}
componentDidMount() {
this._isMounted = true;
AppState.addEventListener('change', this._handleAppStateChange);
}
componentWillUnmount() {
this._isMounted = false;
clearInterval(this.timer);
AppState.removeEventListener('change', this._handleAppStateChange);
}`
Then anywhere where setState is called, I added if(this._isMounted) {}
prior to calling setState. This took care of the async requests while CountDown was unmounted.
I'll paste the entire solution below--it should be a simple copy/paste fix in the index.js file.
`import React from 'react';
import PropTypes from 'prop-types';
import { StyleSheet, View, Text, TouchableOpacity, AppState } from 'react-native';
import _ from 'lodash';
import { sprintf } from 'sprintf-js';
const DEFAULT_DIGIT_STYLE = { backgroundColor: '#FAB913' };
const DEFAULT_DIGIT_TXT_STYLE = { color: '#000' };
const DEFAULT_TIME_LABEL_STYLE = { color: '#000' };
const DEFAULT_SEPARATOR_STYLE = { color: '#000' };
const DEFAULT_TIME_TO_SHOW = ['D', 'H', 'M', 'S'];
const DEFAULT_TIME_LABELS = {
d: 'Days',
h: 'Hours',
m: 'Minutes',
s: 'Seconds',
};
class CountDown extends React.Component {
_isMounted = false;
static propTypes = {
id: PropTypes.string,
digitStyle: PropTypes.object,
digitTxtStyle: PropTypes.object,
timeLabelStyle: PropTypes.object,
separatorStyle: PropTypes.object,
timeToShow: PropTypes.array,
showSeparator: PropTypes.bool,
size: PropTypes.number,
until: PropTypes.number,
onChange: PropTypes.func,
onPress: PropTypes.func,
onFinish: PropTypes.func,
};
state = {
until: Math.max(this.props.until, 0),
lastUntil: null,
wentBackgroundAt: null,
};
constructor(props) {
super(props);
this.timer = setInterval(this.updateTimer, 1000);
}
componentDidMount() {
this._isMounted = true;
AppState.addEventListener('change', this._handleAppStateChange);
}
componentWillUnmount() {
this._isMounted = false;
clearInterval(this.timer);
AppState.removeEventListener('change', this._handleAppStateChange);
}
componentWillReceiveProps(nextProps) {
if (this.props.until !== nextProps.until || this.props.id !== nextProps.id) {
if (this._isMounted) {
this.setState({
lastUntil: this.state.until,
until: Math.max(nextProps.until, 0),
});
}
}
}
_handleAppStateChange = currentAppState => {
const { until, wentBackgroundAt } = this.state;
if (currentAppState === 'active' && wentBackgroundAt && this.props.running) {
const diff = (Date.now() - wentBackgroundAt) / 1000.0;
if (this._isMounted) {
this.setState({
lastUntil: until,
until: Math.max(0, until - diff),
});
}
}
if (currentAppState === 'background') {
if (this._isMounted) {
this.setState({ wentBackgroundAt: Date.now() });
}
}
};
getTimeLeft = () => {
const { until } = this.state;
return {
seconds: until % 60,
minutes: parseInt(until / 60, 10) % 60,
hours: parseInt(until / (60 * 60), 10) % 24,
days: parseInt(until / (60 * 60 * 24), 10),
};
};
updateTimer = () => {
const { lastUntil, until } = this.state;
if (lastUntil === until || !this.props.running) {
return;
}
if (until === 1 || (until === 0 && lastUntil !== 1)) {
if (this.props.onFinish) {
this.props.onFinish();
}
if (this.props.onChange) {
this.props.onChange(until);
}
}
if (until === 0) {
if (this._isMounted) {
this.setState({ lastUntil: 0, until: 0 });
}
} else {
if (this.props.onChange) {
this.props.onChange(until);
}
if (this._isMounted) {
this.setState({
lastUntil: until,
until: Math.max(0, until - 1),
});
}
}
};
renderDigit = d => {
const { digitStyle, digitTxtStyle, size } = this.props;
return (
<View style={[styles.digitCont, digitStyle, { width: size * 2.3, height: size * 2.6 }]}>
<Text style={[styles.digitTxt, { fontSize: size }, digitTxtStyle]}>{d}</Text>
</View>
);
};
renderLabel = label => {
const { timeLabelStyle, size } = this.props;
if (label) {
return <Text style={[styles.timeTxt, { fontSize: size / 1.8 }, timeLabelStyle]}>{label}</Text>;
}
};
renderDoubleDigits = (label, digits) => {
return (
<View style={styles.doubleDigitCont}>
<View style={styles.timeInnerCont}>{this.renderDigit(digits)}</View>
{this.renderLabel(label)}
</View>
);
};
renderSeparator = () => {
const { separatorStyle, size } = this.props;
return (
<View style={{ justifyContent: 'center', alignItems: 'center' }}>
<Text style={[styles.separatorTxt, { fontSize: size * 1.2 }, separatorStyle]}>{':'}</Text>
</View>
);
};
renderCountDown = () => {
const { timeToShow, timeLabels, showSeparator } = this.props;
const { until } = this.state;
const { days, hours, minutes, seconds } = this.getTimeLeft();
const newTime = sprintf('%02d:%02d:%02d:%02d', days, hours, minutes, seconds).split(':');
const Component = this.props.onPress ? TouchableOpacity : View;
return (
<Component style={styles.timeCont} onPress={this.props.onPress}>
{timeToShow.includes('D') ? this.renderDoubleDigits(timeLabels.d, newTime[0]) : null}
{showSeparator && timeToShow.includes('D') && timeToShow.includes('H')
? this.renderSeparator()
: null}
{timeToShow.includes('H') ? this.renderDoubleDigits(timeLabels.h, newTime[1]) : null}
{showSeparator && timeToShow.includes('H') && timeToShow.includes('M')
? this.renderSeparator()
: null}
{timeToShow.includes('M') ? this.renderDoubleDigits(timeLabels.m, newTime[2]) : null}
{showSeparator && timeToShow.includes('M') && timeToShow.includes('S')
? this.renderSeparator()
: null}
{timeToShow.includes('S') ? this.renderDoubleDigits(timeLabels.s, newTime[3]) : null}
</Component>
);
};
render() {
return <View style={this.props.style}>{this.renderCountDown()}</View>;
}
}
CountDown.defaultProps = {
digitStyle: DEFAULT_DIGIT_STYLE,
digitTxtStyle: DEFAULT_DIGIT_TXT_STYLE,
timeLabelStyle: DEFAULT_TIME_LABEL_STYLE,
timeLabels: DEFAULT_TIME_LABELS,
separatorStyle: DEFAULT_SEPARATOR_STYLE,
timeToShow: DEFAULT_TIME_TO_SHOW,
showSeparator: false,
until: 0,
size: 15,
running: true,
};
const styles = StyleSheet.create({
timeCont: {
flexDirection: 'row',
justifyContent: 'center',
},
timeTxt: {
color: 'white',
marginVertical: 2,
backgroundColor: 'transparent',
},
timeInnerCont: {
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
},
digitCont: {
borderRadius: 5,
marginHorizontal: 2,
alignItems: 'center',
justifyContent: 'center',
},
doubleDigitCont: {
justifyContent: 'center',
alignItems: 'center',
},
digitTxt: {
color: 'white',
fontWeight: 'bold',
fontVariant: ['tabular-nums'],
},
separatorTxt: {
backgroundColor: 'transparent',
fontWeight: 'bold',
},
});
module.exports = CountDown;
`
from react-native-countdown-component.
I also have this issue, and the above solution looked promising but ended up breaking the component. Timer doesn't change from 0 0 0 now
from react-native-countdown-component.
I also have this issue, and the above solution looked promising but ended up breaking the component. Timer doesn't change from 0 0 0 now
Are you saying it doesn't change from 0 0 0 when finishing? I restart the timer by feeding in a new time for the "until" prop using the "onFinish" prop.
`nextChoices = () => {
const numOfQuestions = this.props.questions.length;
if (this.state.questionNumber + 1 === numOfQuestions) {
if (this._isMounted) {
this.setState({
stopTimer: true,
});
Actions.scoresheet();
}
} else {
// this.setState({
// stopTimer: true
// })
this.nextQuestion();
}
};
resetTimer = () => {
if (this._isMounted) {
this.setState({
remainingTime: this.state.timerNumber,
});
}
};
renderTimer = () => {
if (this._isMounted) {
setTimeout(() => {
this.setState({ timerDisabled: false });
}, 100);
}
if (this.state.timerDisabled) {
return <Text>Loading</Text>;
} else {
return (
<CountDown
until={this.state.timerNumber}
onFinish={() => this.nextChoices()}
running={!this.state.stopTimer}
timeToShow={['M', 'S']}
digitStyle={{ backgroundColor: '#5084a3' }}
onChange={timeLeft => this.getData(timeLeft)}
/>
);
}
};`
from react-native-countdown-component.
when timer is runnig out i remove the countdown but got warning "can't perform react state update on an unmounted component".
i think it is because we have to clearinterval the timer, but how to do that?
The timer interval is already being cleared in the componentWillUnmount lifecycle method in the index.js file located in the the react-native-countdown-component node_module folder.
from react-native-countdown-component.
setTimeout(() => {
this.setState({ showCountDown: false })
}, 100)
This worked for me. Thanks a lot pal!
btw, can you explain why we use setTimeout() to fix the warning?
from react-native-countdown-component.
I was able to mitigate this error in another way. I just set display:none in the countdown element's style when the countdown finishes. So it doesn't unmount at all.
from react-native-countdown-component.
Related Issues (20)
- Maximum update depth exceeded HOT 3
- Peer dependency error
- until does not update when state.property is changed - stays one update behind. HOT 6
- SOLVED accuracy
- Dead?
- How can I get the value of the elapsed time to save it in localstorge? HOT 1
- onFinish not work on 00 HOT 1
- EventEmitter needs update HOT 1
- Deprecated AppState.removeEventListener on react v0.70 HOT 9
- Error -4049
- Android Timer decrease with in seconds (very fastly) HOT 5
- AppState.removeEventListener() is deprecated which is used in the index.js file
- EventEmitter.removeListener('appStateDidChange', ...): Method has been deprecated. Please instead use `remove()` on the subscription returned by `EventEmitter.addListener`. HOT 2
- Save yourself a headache: HOT 2
- undefined is not a function (AppState.removeEventListener('change', this._handleAppStateChange) HOT 3
- Volunteer as Maintainer
- maintaining this component
- 'removeEventListener' removed in recent versions of react-native. Replaced with '.remove()'
- Countdown not working well beyond 24 hours
- Maximum update depth exceeded. HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from react-native-countdown-component.