You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何this.setState()触发已卸载组件警告?请求排查代码问题

Fixing "Can only update a mounted or mounting component" Warning in React Native

Let's break down exactly what's happening here and fix this warning step by step.

Why You're Seeing This Warning

That warning pops up because when you navigate back from your roles2 page to home, your Empty component gets unmounted from the screen. But the Firestore async request you started earlier (with db.collection("roles").get()) is still running in the background. When it finishes, it tries to call setState on a component that no longer exists—hence the error.

Step 1: Remove the Unnecessary componentWillUpdate Logic

First off, your componentWillUpdate method is causing way more problems than it solves. It fires every time the component updates, which means you're spawning duplicate Firestore requests constantly. Delete this entire block:

componentWillUpdate(nextProps, nextState) {
  this.roles = db.collection("roles").get();
  this.setItemsFromFirestore(this.roles);
}

You already fetch data in componentDidMount—this extra fetch is redundant and creates more opportunities for memory leaks.

Step 2: Add a Mounted Flag to Block Post-Unmount setState

We'll add a simple flag to track if the component is still mounted, so we only call setState when it's safe. Update your component code like this:

constructor(props) {
  super(props);
  this.ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2})
  this.state = {
    dataSource: this.ds.cloneWithRows(list),
  };
  this._isMounted = false; // Initialize our mounted flag
  this.renderItem = this.renderItem.bind(this)
  this.setItemsFromFirestore = this.setItemsFromFirestore.bind(this);
}

componentDidMount() {
  this._isMounted = true; // Mark component as mounted when it loads
  const roles = db.collection("roles").get();
  this.setItemsFromFirestore(roles);
}

componentWillUnmount() {
  this._isMounted = false; // Mark as unmounted when navigating away
}

setItemsFromFirestore(roles) {
  roles.then((querySnapshot) => {
    var items = [];
    querySnapshot.forEach((child) => {
      items.push({
        label: `${child.data().label}`,
        description: `${child.data().description}`,
        id: `${child.id}`
      });
    });
    // Only update state if the component is still mounted!
    if (this._isMounted) {
      this.setState({
        dataSource: this.ds.cloneWithRows(items),
      });
    }
  });
}

If your roles data might update while the component is active, using onSnapshot instead of get() will give you real-time updates and let you clean up the listener properly when the component unmounts. Here's how to refactor that:

constructor(props) {
  super(props);
  this.ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2})
  this.state = {
    dataSource: this.ds.cloneWithRows(list),
  };
  this._isMounted = false;
  this._firestoreUnsubscribe = null; // Store the unsubscribe function
  this.renderItem = this.renderItem.bind(this);
}

componentDidMount() {
  this._isMounted = true;
  // Set up real-time listener
  this._firestoreUnsubscribe = db.collection("roles").onSnapshot((querySnapshot) => {
    var items = [];
    querySnapshot.forEach((child) => {
      items.push({
        label: `${child.data().label}`,
        description: `${child.data().description}`,
        id: `${child.id}`
      });
    });
    if (this._isMounted) {
      this.setState({
        dataSource: this.ds.cloneWithRows(items),
      });
    }
  });
}

componentWillUnmount() {
  this._isMounted = false;
  // Clean up the Firestore listener to stop updates
  if (this._firestoreUnsubscribe) {
    this._firestoreUnsubscribe();
  }
}

Quick Bonus Fixes

  • Stop using ListView: React Native has deprecated ListView in favor of FlatList/SectionList—they're more performant and have better built-in features.
  • Fix list item keys: Using Uuid() in renderItem creates a new key every render, which hurts performance. Use the Firestore document ID instead: <Item key={item.id} ... />

内容的提问来源于stack exchange,提问作者Matthias Wegner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 06:35:40