Reactjs 获得;Can';t对未安装的组件执行React状态更新“;在屏幕之间切换时

Reactjs 获得;Can';t对未安装的组件执行React状态更新“;在屏幕之间切换时,reactjs,react-native,google-cloud-firestore,Reactjs,React Native,Google Cloud Firestore,在Home.js和Chat.js文件之间切换时,我收到以下警告:“无法对已卸载的组件执行React状态更新。这是no op,但表示应用程序内存泄漏。若要修复此问题,请取消componentWillUnmount方法中的所有订阅和异步任务。”。我删除了Chat.js上唯一的侦听器,并尝试仅在组件装入Home.js时设置状态,然后在卸载时将其删除,但仍然收到此警告 Home.js import React, { Component } from "react"; import { View, Fla

在Home.js和Chat.js文件之间切换时,我收到以下警告:“无法对已卸载的组件执行React状态更新。这是no op,但表示应用程序内存泄漏。若要修复此问题,请取消componentWillUnmount方法中的所有订阅和异步任务。”。我删除了Chat.js上唯一的侦听器,并尝试仅在组件装入Home.js时设置状态,然后在卸载时将其删除,但仍然收到此警告

Home.js

import React, { Component } from "react";
import { View, FlatList } from "react-native";
import { ListItem } from "react-native-elements";
import fireStoreDB from "../database/FirestoreDB";

let _isMounted = false;

export default class Home extends Component {
  constructor(props) {
    super(props);
    this.state = {
      usersInfo: [],
      refreshing: false
    };
  }

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

  componentWillUnmount() {
    _isMounted = false;
  }

  LoadUsers = () => {
    fireStoreDB
      .getAllUsersExceptCurrent()
      .then(users =>
        Promise.all(
          users.map(({ id, username, avatar }) =>
            fireStoreDB
              .getUserLastMessage(fireStoreDB.getUID, id)
              .then(message => ({ id, username, avatar, message }))
          )
        )
      )
      .then(users => {
        if (_isMounted) {
          this.setState({
            usersInfo: users.filter(x => typeof x.avatar !== "undefined"),
            refreshing: false
          });
        }
      });
  };

  renderItem = ({ item }) => (
    <ListItem
      onPress={() => {
        this.props.navigation.navigate("Chat", {
          userTo: item.id,
          UserToUsername: item.username,
          LoadUsers: this.LoadUsers
        });
      }}
      title={item.username}
      subtitle={item.message}
      leftAvatar={{ source: { uri: item.avatar } }}
      bottomDivider
      chevron
    />
  );

  render() {
    return (
      <View>
        <FlatList
          data={this.state.usersInfo}
          renderItem={this.renderItem}
          keyExtractor={item => item.id}
          refreshing={this.state.refreshing}
          onRefresh={() => {
            this.setState({ refreshing: true });
            this.LoadUsers();
          }}
        />
      </View>
    );
  }
}
更新: 在您的实现中,您不能取消贿赂
消息
集合。 您可以尝试从
getMessages
返回unsubscribe函数,然后在
componentWillUnmount

FirestoreDB.js

  removeSnapshotListener = chatId => {
    firebase
      .firestore()
      .collection("messages")
      .doc(chatId)
      .collection("chats")
      .orderBy("createdAt")
      .onSnapshot(() => {});
  };
getMessages = (callback, chatId) => {
  return firebase
      .firestore()
      .collection("messages")
      .doc(chatId)
      .collection("chats")
      .orderBy("createdAt")
      .onSnapshot(callback);
}
Chat.js

import React, { Component } from "react";
import { View, KeyboardAvoidingView } from "react-native";
import { HeaderBackButton } from "react-navigation-stack";
import { GiftedChat } from "react-native-gifted-chat";
import * as Progress from "react-native-progress";
import fireStoreDB from "../database/FirestoreDB";

const Themes = {
  primaryTheme: "#30D921",
  secondaryTheme: "#B32D83",
  layoutTheme: "#c0c0c0"
};

export default class Chat extends Component {
  static navigationOptions = ({ navigation }) => ({
    title: navigation.getParam("UserToUsername"),
    headerLeft: (
      <HeaderBackButton
        onPress={() => {
          navigation.state.params.LoadUsers();
          navigation.goBack();
        }}
      />
    )
  });

  constructor(props) {
    super(props);
    this.state = {
      messages: [],
      userToId: this.props.navigation.getParam("userTo")
    };
  }

  componentDidMount() {
    fireStoreDB.getMessages(
      message =>
        this.setState(previousState => ({
          messages: GiftedChat.append(previousState.messages, message)
        })),
      this.chatId
    );
  }

  componentWillUnmount() {
    fireStoreDB.removeSnapshotListener(this.chatId);
  }

  // gifted chat user props
  get user() {
    return {
      _id: fireStoreDB.getUID,
      name: fireStoreDB.getName,
      avatar: fireStoreDB.getAvatar
    };
  }

  // merge ids between two parties for one to one chat
  get chatId() {
    const userFromId = fireStoreDB.getUID;
    const chatIdArray = [];
    chatIdArray.push(userFromId);
    chatIdArray.push(this.state.userToId);
    chatIdArray.sort(); // prevents other party from recreating key
    return chatIdArray.join("_");
  }

  render() {
    if (this.state.messages.length === 0) {
      return (
        <View
          style={{
            alignItems: "center",
            marginTop: 260
          }}
        >
          <Progress.Bar indeterminate color={Themes.primaryTheme} />
        </View>
      );
    }
    return (
      <View style={{ flex: 1 }}>
        <GiftedChat
          messages={this.state.messages}
          onSend={messages => fireStoreDB.sendMessages(messages, this.chatId)}
          user={this.user}
        />
        <KeyboardAvoidingView behavior="padding" keyboardVerticalOffset={80} />
      </View>
    );
  }
}
  componentDidMount() {
    this.unsubcribe = fireStoreDB.getMessages(
      message =>
        this.setState(previousState => ({
          messages: GiftedChat.append(previousState.messages, message)
        })),
      this.chatId
    );
  }

  componentWillUnmount() {
     this.unsubcribe();
  }

第一个没有修复错误,第二个与我的相同。你的版本包含
括号
符号(
{
),因此它无法返回正确的
取消订阅
函数hi@cluther,我只是更新我的答案。请检查它是否可以修复你的问题我得到“TypeError:this.unsubscribe不是函数”当调用
this.unsubscribe()
但当我这样调用
this.unsubscribe
时,我仍然会收到警告。您可以调试
fireStoreDB.getMessages
是否返回任何内容吗?您可以在此处查看文档