Reactjs 获得;Can';t对未安装的组件执行React状态更新“;在屏幕之间切换时
在Home.js和Chat.js文件之间切换时,我收到以下警告:“无法对已卸载的组件执行React状态更新。这是no op,但表示应用程序内存泄漏。若要修复此问题,请取消componentWillUnmount方法中的所有订阅和异步任务。”。我删除了Chat.js上唯一的侦听器,并尝试仅在组件装入Home.js时设置状态,然后在卸载时将其删除,但仍然收到此警告 Home.jsReactjs 获得;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
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
是否返回任何内容吗?您可以在此处查看文档