2017-10-19 49 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

謝謝你,你的解決方案。這行得通! –

相關問題