我尝试创建一个倒数计时器,发现setState
在一个间隔内消耗大量内存,并且会一直增长直到崩溃。
我尝试使用react-native init intervaltest
然后我在App.js中得到了
import React, { Component } from "react";
import { StyleSheet, Text, View } from "react-native";
type Props = {};
export default class App extends Component<Props> {
state = {
countdownNumber: 10000000
};
componentDidMount = () => {
if (!this.interval) {
this.interval = setInterval(() => {
this.setState(prevState => ({
countdownNumber: prevState.countdownNumber - 1
}));
}, 10);
}
};
render() {
const { countdownNumber } = this.state;
return (
<View style={styles.container}>
<Text style={styles.welcome}>{countdownNumber}</Text>
</View>
);
}
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: "center",
alignItems: "center",
backgroundColor: "#F5FCFF"
},
welcome: {
fontSize: 20,
textAlign: "center",
margin: 10
},
});
反正这是一个非常简单的代码。有什么方法可以解决react-native的这种记忆渴行为吗?
答案 0 :(得分:0)
在您的代码中,setInterval
被调用componentDidMount
,而componetDidMount
将被整个component life-cycle
调用一次。因此,setInterval中的函数将仅被调用一次。也就是说,在第一次渲染之后但在连续渲染之后,componentDidMount
不会被调用。
简单的解决方案是:
export default class App extends Component<Props> {
state = {
countdownNumber: 10000000
};
componentDidMount = () => {
if (!this.interval) {
this.interval = setInterval(() => {
this.setState(prevState => ({
countdownNumber: prevState.countdownNumber - 1
}));
}, 10);
}
};
componentDidUpdate(){
if(this.state.countdownNumber === 1){
clearInterval(this.interval);
}
}
componentWillUnmount(){
clearInterval(this.interval);
}
render() {
const { countdownNumber } = this.state;
return (
<View style={styles.container}>
<Text style={styles.welcome}>{countdownNumber}</Text>
</View>
);
}
}
Memory leak due to setInterval :::如果我们在调用unmount
之前clearInterval
个组件,则会发生内存泄漏,因为interval
中设置的componentDidMount
会启动计时器并且在卸下组件时计时器不会停止。 React提供了componentWillUnmount
生命周期方法,作为清除组件为unmounted
/ removed
时需要清除的所有内容的机会。