setState(...):只能更新已安装或已安装的组件。这通常意味着您在卸载的组件上调用了setState()。这是无操作的
问题描述:
只能更新已安装或已安装的组件。这通常表示 您在未安装的组件上调用setState,replaceState或forceUpdate。这是一个没有操作。setState(...):只能更新已安装或已安装的组件。这通常意味着您在卸载的组件上调用了setState()。这是无操作的
请检查Menu组件的代码。
我不知道会发生什么。我只是在我的项目中发现这个错误。我不太了解这个错误,因为这个错误并没有给我具体的信息。现在,我困惑这个错误让我有点强调
export default class Menu extends Component {
constructor(){
super();
this.state = {
user: {},
loading: true,
dataSource: new ListView.DataSource({rowHasChanged: (row1, row2) => row1 !== row2 }),
items: [],
}
}
componentDidMount(){
AsyncStorage.getItem('userData').then((user) => {
let userData = JSON.parse(user)
this.setState({
user: userData,
})
})
firebase.database().ref('Posts').limitToLast(10).on('value', (snap) => {
console.log('new', snap.val())
snap.forEach((child) => {
this.state.items.push({
title: child.val().title,
key: child.key,
author: child.val().authorName,
image: child.val().picture,
price: child.val().price,
description: child.val().description,
stock: child.val().stock,
authorId: child.val().authorId
});
});
this.setState({
dataSource: this.state.dataSource.cloneWithRows(this.state.items),
loading:false
});
});
}
logOut(){
AsyncStorage.removeItem('userData').then(() => {
firebase.auth().signOut();
this.props.navigation.navigate('Index')
})
}
renderRow(data) {
return (
<View style={styles.listProduct} key={data.key}>
<TouchableOpacity
onPress={() => this.props.navigation.navigate('Detail', {data})}
>
<Text style={styles.titleProduct}> {data.title} </Text>
<Text style={styles.textProduct}>{data.author}</Text>
<Image
source={{ uri:data.image }}
style={{
height: 150,
width: 150,
alignSelf: 'center',
}}
/>
</TouchableOpacity>
<View style={styles.postInfo}>
<Text style={styles.textProduct}>Rp.{data.price}</Text>
</View>
</View>
)
}
render(){
if (this.state.loading){
return <ActivityIndicator size="large" />
}
console.ignoredYellowBox = ['Remote debugger'];
console.ignoredYellowBox = ['Setting a timer'];
console.log(this.state.user)
const { navigate } = this.props.navigation
return(
<ScrollView>
<View style={styles.container}>
<View style={styles.header}>
<TouchableOpacity onPress={()=> this.props.navigation.navigate('Checkout')}>
<Icon name='md-cart' size={30} color='#eee'/>
</TouchableOpacity>
<View>
<TouchableOpacity onPress={this.logOut.bind(this)}>
<Icon name='ios-log-out-outline' size={30} color='#eee' />
</TouchableOpacity>
</View>
<View style={styles.addItem}>
<TouchableOpacity onPress={() => this.props.navigation.navigate('Add')}>
<Icon name='md-add' size={30} color='#eee' />
</TouchableOpacity>
</View>
</View>
<ListView
dataSource={this.state.dataSource}
renderRow={this.renderRow.bind(this)}
enableEmptySections={true}
/>
</View>
</ScrollView>
)
}
}
答
您需要删除事件侦听器的任何其他类型的听众,当你未安装的组件。 Firebase查询正尝试更新状态事件,虽然组件已卸载。您可以使用off
方法来移除Firebase的侦听器。
你的代码的另一个可能的问题是你直接操纵状态值。这不是一个好习惯。下面的代码是一个例子,说明如何通过你已经尝试做的事来达到类似的效果。
例
onData = (snap) => {
console.log('new', snap.val())
snap.forEach((child) => {
this.setState((prevState) => {
const newState = Object.assign({}, prevState);
newState.items.push({
title: child.val().title,
key: child.key,
author: child.val().authorName,
image: child.val().picture,
price: child.val().price,
description: child.val().description,
stock: child.val().stock,
authorId: child.val().authorId
});
return newState;
});
});
this.setState({
dataSource: this.state.dataSource.cloneWithRows(this.state.items),
loading:false
});
}
componentDidMount(){
AsyncStorage.getItem('userData').then((user) => {
let userData = JSON.parse(user)
this.setState({
user: userData,
})
})
firebase.database().ref('Posts').limitToLast(10).on('value', this.onData);
}
componentWillUnmount() {
firebase.database().ref('Posts').limitToLast(10).off('value', this.onData);
}
谢谢你,你的解决方案。这行得通! –