首页 > 解决方案 > 如何修复“无法在未安装的组件上执行 React 状态更新”。React Native 中的错误

问题描述

我在我的本地数据库(sqlite)中获取数据并更新状态,并且出现了这个错误:

无法对未安装的组件执行 React 状态更新。这是一个 >no-op,但它表明您的应用程序中存在内存泄漏。要解决此问题,请在 >componentWillUnmount 方法中 >cancel 所有订阅和异步任务。

没有解决方案帮助我。


_isMounted = false;
  constructor(props) {
    super(props);
    this.state = {
      slug: "",
      value: "",
      cod_year: "",
      months: [],
      years: [],
      loadingData: true,
    };
  }
  db = openDatabase({ name: 'test.db', createFromLocation : '~my_finances.db'});

  getYears = () => {
    if(this.state.loadingData){
      this.db.transaction((txn)=>{
        txn.executeSql(
            "SELECT cod, slug FROM year",
            [],
            (tx, res) => {
                if(res.rows.length > 0){
                    rows = [];
                    for(let i=0; i<res.rows.length;i++){
                        rows.push(res.rows.item(i));
                    }
                    this.setState({years: rows}, {loadingData: false});
                }
            }
        )
      })
    }

  }

  componentDidMount(){
    this._isMounted = true;
    this.getYears();
  }

  render() {
    const state = this.state;
    if(!state.loadingData){
      const pickerItens = state.years.map((record, index) => {
        <Picker.Item label={record.slug} value={record.cod}/>  
      })
      return (
        <View style={{flex: 1}} >
          <ScrollView style={styles.container}>
            <View style={styles.form_add}>
              <Text style={styles.form_slug} > Adicionar </Text>
              <TextInput 
                  placeholder="Digite o mês..."
                  onChangeText={(slug) => { this.setState({slug}) }}
                  value={this.state.slug}
                  style={styles.input_add}
              />
              <TextInput 
                  placeholder="Digite o valor..."
                  onChangeText={(value) => { this.setState({value}) }}
                  value={this.state.value}
                  style={styles.input_add}
              />
              <Picker onValueChange = {(cod_year) => {this.setState({cod_year})}}>
                { pickerItens }
              </Picker>

              <Button color="#7159C1" title="Salvar" onPress={() => this.addYear()} /> 
            </View>
          </ScrollView>
          <Footer navigate={this.props.navigation.navigate} />
        </View>
      );
    }else{
      <Text> Loading... </Text>
    }
  }

标签: javascriptandroidreact-native

解决方案


每当有任何任务正在运行并且您通过导航返回屏幕时,

出现此警告,

您无需担心任何事情。

这是正常的警告。

假设你已经完成setState它正在运行并且你卸载了所有东西。所以这里的系统会认为我正在做setState,但我没有类,这个,或/和变量来做它。

所以它只是警告你一切都被卸载了,我不能在卸载的组件上这样做。

关于杀死异步任务......,

假设您已经设置了一个 1 分钟的计时器,并且您每 1 分钟setState对状态变量进行一次操作。

let this.timerState = setTimeout(() => {
  this.setState({ timer: this.state.timer + 1 });
}, 1000);

现在无论你做什么,这个一分钟的计时器都会无限运行,直到你杀死你的应用程序。

因此系统建议您在卸载组件时终止此类任务。

clearTimeout(this.timerState)生命周期法也是如此componentWillunmount

所以不要担心警告没有什么可以泄露的。


推荐阅读