2017-10-19 64 views
1

只能更新已安装或已安装的组件。这通常表示 您在未安装的组件上调用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> 
     ) 
    } 
} 

回答

3

您需要删除事件侦听器的任何其他类型的听众,当你未安装的组件。 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); 
} 
+1

谢谢你,你的解决方案。这行得通! –

相关问题