setState占用大量内存

时间:2019-06-10 09:10:06

标签: react-native

我尝试创建一个倒数计时器,发现setState在一个间隔内消耗大量内存,并且会一直增长直到崩溃。

我尝试使用react-native init intervaltest

创建一个全新的react-native应用程序

然后我在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的这种记忆渴行为吗?

1 个答案:

答案 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时需要清除的所有内容的机会。