2017-10-19 3 views
1

Peut uniquement mettre à jour un composant monté ou monté. Cela signifie généralement que vous avez appelé setState, replaceState ou forceUpdate sur un composant non monté. C'est un no-op.setState (...): Ne peut mettre à jour qu'un composant monté ou monté. Cela signifie généralement que vous avez appelé setState() sur un composant non monté. Ceci est un no-op

Veuillez vérifier le code du composant Menu.

Je ne sais pas ce qui se passe. Je continue à trouver cette erreur dans mon projet. Je ne comprends pas vraiment cette erreur car cette erreur ne me donne pas d'informations spécifiques. Maintenant, je confondais cette erreur m'a fait peu stressée

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> 
     ) 
    } 
} 

Répondre

3

Vous devez supprimer les écouteurs d'événements tout autre type d'auditeurs lorsque vous montez un-composant. La requête Firebase tente de mettre à jour l'événement d'état bien que le composant soit démonté. Vous pouvez utiliser la méthode off pour supprimer les écouteurs de Firebase.

Un autre problème possible avec votre code est que vous manipulez des valeurs d'état directement. Ce n'est pas une bonne pratique. Le code ci-dessous est un exemple de la façon dont vous pouvez obtenir un effet similaire avec ce que vous essayez déjà de faire.

Exemple

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

Merci monsieur pour votre solution. Ça marche! –