我收到警告“只能更新已安装或安装的组件。这通常意味着您在未安装的组件上调用了setState,replaceState或forceUpdate。这是following code的无操作”。在GitHub,您可以找到firebase和Redux的完整工作反应导航示例。如果一个比我更熟练的人看到代码,我认为可以看到问题。
当我从“roles2”跳到“home”导航时,我不知道如何补偿这个警告。你能找到这个bug吗?
import React, { Component } from "react";
import { Text, View, TouchableHighlight, TouchableOpacity, ListView, StatusBar, ScrollView, StyleSheet } from "react-native";
import Styles from "./../../App.scss";
import Firebase from "./../Util/database";
import Item from "./item";
const Uuid = require('uuid/v1');
import FontAwesome from 'react-native-vector-icons/FontAwesome';
import { NavigationActions, SafeAreaView } from "react-navigation";
import { connect } from "react-redux";
var db = Firebase.firestore();
const list = ['Loading...']
export default class Empty extends Component {
constructor(props) {
super(props);
this.ds = new ListView.DataSource({rowHasChanged: (r1, r2) => r1 !== r2})
this.state = {
dataSource: this.ds.cloneWithRows(list),
};
this.roles = db.collection("roles").get();
this.renderItem = this.renderItem.bind(this)
this.setItemsFromFirestore = this.setItemsFromFirestore.bind(this);
}
setItemsFromFirestore(roles) {
roles.then((querySnapshot) => {
// get children as an array
var items = [];
querySnapshot.forEach((child) => {
items.push({
label: `${child.data().label}`,
description: `${child.data().description}`,
id: `${child.id}`
});
});
this.setState({
dataSource: this.ds.cloneWithRows(items),
});
});
}
componentWillUpdate(nextProps, nextState) {
this.roles = db.collection("roles").get();
this.setItemsFromFirestore(this.roles);
}
componentDidMount() {
this.setItemsFromFirestore(this.roles);
}
renderItem(item, navigation) {
return (
<Item key={Uuid()} label={item.label} description={item.description} onPress={ () => {
const param = item.param;
const route = item.route;
const navigateAction = NavigationActions.navigate({
routeName: 'role',
params: {
label: `${item.label}`,
description: `${item.description}`,
id: `${item.id}`
}
});
navigation.dispatch(navigateAction);
}} />
)
}
static navigationOptions = props => {
const { navigation } = props;
const { state, setParams } = navigation;
const { params } = state;
return {
title: "Rollen (Cloud)",
headerTintColor: Styles.ci_Header.color,
headerStyle: {
height: Styles.ci_Header.height,
backgroundColor: Styles.ci_Header.backgroundColor
},
headerRight: (
<FontAwesome
name= {'plus'}
size={18}
style={{ color: Styles.ci_Header.color, paddingHorizontal: 5}}
onPress={() => {
const id = `${Uuid()}`;
var data = {
id: {id},
label: `Neue Rolle (${id.substring(0,6)}...)`,
description: ''
};
var setDoc = db.collection('roles').doc(id).set(data);
}}
/>
)
};
};
render() {
return (
<View style={{ flex: 1 }}>
<ListView
dataSource={this.state.dataSource}
renderRow={item => this.renderItem(item, this.props.navigation)} />
<StatusBar barStyle="light-content" />
</View>
);
}
}
我是新手,对导航做出反应,并没有得到我做错的事。
你能找到这个错误吗?
答案 0 :(得分:2)
此错误表示即使在卸载组件后也调用了setState方法。这通常是由异步API调用引起的。因此,在您移动到其他页面后,您的API调用会返回结果。要避免此警告,可以在 componentDidMount 的组件类中将变量设置为true,并在调用setState方法之前检查该变量是否具有true值。
componentDidMount(){
this.isMounted = true;
}
fetchData(){
if(this.isMounted){
this.setState();
}
}
答案 1 :(得分:0)
我找到了解决方案,但并不满意。我用
this.mounted = false;
this.state = {
isMounted: true,
...
};
在卸载时我使用
componentWillUnmount() {
this.mounted = false;
this.setState( {isMounted: false} );
console.log('Will Unmount '+componentName);
}
现在看。在componentWillUpdate
i log
console.log("mounted?: "+this.state.isMounted +" (isMounted-Stat) - "+this.mounted+" (mounted)");
并且控制台抛出
13:28:53: Will Update roles2
13:28:53: Will Unmount roles2
13:28:53: mounted?: true (isMounted-Stat) - false (mounted)
这意味着当我将其定义为组件内的参数时,我可以使用this.mounted
,但状态不会使用Unmount进行更新。这在我看来不合逻辑,但我和它一起生活。使用此解决方案(constructor
,componentWillUnmount
,componentWillUpdate
),它可以正常运行并且警告已经消失。
我真的很喜欢更好的方法,因为在Unmount之后放置组件时会发出警告。因此,即使组件保持未安装状态,也会调用函数setState
。当我在卸载中调用setState
时,参数未设置。