2016-12-12 9 views
2

このエラーを取り除くことはできません。それは私の配列から1つの項目を削除し、状態を更新するときに起こっている。警告:setState(...):マウントされたコンポーネントまたはマウントされているコンポーネントのみを更新できます

デバッグした後、私はアプリをリロードしてこの画面に直接行き、削除してもエラーは表示されないことを発見しました。 しかし、この画面に移動して戻ってこの画面に戻って、削除すると、エラーが表示されます。私が画面を10回ロードすると、このようなエラー(30)が出ます。

私の推測では、ダッシュボードにポップルートを戻すときにfirebase接続を終了していないと思います。または、私が使用しているナビゲータが正しくシーンをアンロードしていない。または、deleteRow()関数に問題があります

私は本当に他に何もできません。同じ質問はウェブ上にありますが、私のシナリオには当てはまらないようです。

constructor(props) { 
    super(props); 
    this.state = { 
     dataSource: new ListView.DataSource({ 
     rowHasChanged: (row1, row2) => row1 !== row2, 
     }), 
    }; 

    const user = firebase.auth().currentUser; 
    if (user != null) { 
     this.itemsRef = this.getRef().child(`Stores/${user.uid}/`); 
    } else { 
     Alert.alert('Error', 'error!'); 
    } 
    this.connectedRef = firebase.database().ref('.info/connected'); 
    } 

    componentWillMount() { 
    this.connectedRef.on('value', this.handleValue); 
    } 

    componentWillReceiveProps() { 
    this.connectedRef.on('value', this.handleValue); 
    } 

    componentWillUnmount() { 
    this.connectedRef.off('value', this.handleValue); 
    } 

    /*eslint-disable */ 
    getRef() { 
    return firebase.database().ref(); 
    } 
    /*eslint-enable */ 

    handleValue = (snap) => { 
    if (snap.val() === true) { 
     this.listenForItems(this.itemsRef); 
    } else { 
     //this.offlineForItems(); 
    } 
    }; 

    listenForItems(itemsRef) { 
    this.itemsRef.on('value', (snap) => { 
     const items = []; 
     snap.forEach((child) => { 
     items.unshift({ 
      title: child.val().title, 
      _key: child.key, 
     }); 
     }); 
     offline2.save('itemsS', items); 
     this.setState({ 
     dataSource: this.state.dataSource.cloneWithRows(items), 
     }); 
    }); 
    } 

    offlineForItems() { 
    offline2.get('itemsS').then((items) => { 
     this.setState({ 
     dataSource: this.state.dataSource.cloneWithRows(items), 
     }); 
    }); 
    } 

    deleteConfirm(data, secId, rowId, rowMap) { 
    Alert.alert(
     'Warning!', 
     'Are you sure?', 
     [ 
      { text: 'OK', onPress:() => this.deleteRow(data, secId, rowId, rowMap) }, 
      { text: 'Cancel', onPress:() => this.deleteCancel(data, secId, rowId, rowMap) }, 
     ] 
    ); 
    } 

    deleteCancel(data, secId, rowId, rowMap) { 
    rowMap[`${secId}${rowId}`].closeRow(); 
    } 

    deleteRow(data, secId, rowId, rowMap) { 
    rowMap[`${secId}${rowId}`].closeRow(); 
    this.itemsRef.child(data._key).remove(); 
    offline2.get('itemsS').then((items) => { 
     const itemsTemp = items; 
     let index = -1; 
     for (let i = 0; i < itemsTemp.length; i += 1) { 
     if (itemsTemp[i]._key === data._key) { 
      index = i; 
     } 
     } 
     if (index > -1) { 
     itemsTemp.splice(index, 1); 
     } 
     // Decrement stores counter 
     offline2.get('storesTotal').then((value) => { 
     const itemsReduce = value - 1; 
     this.setState({ storesValue: itemsReduce }); 
     offline2.save('storesTotal', itemsReduce); 
     }); 

     offline2.save('itemsS', itemsTemp); 
     this.setState({ 
     dataSource: this.state.dataSource.cloneWithRows(itemsTemp), 
     }); 
    }); 
    } 

答えて

1

私はそれがあなたにつながっている場合、エラーを確認していないが、これは誤りである、あなたは(イベントリスナーを削除します)バインド解除したいから、あなたがっ、好ましくはあなたのコンストラクタで、あなたのイベントハンドラをバインドする必要があります同じ機能を参照する必要があります。

constructor(props) { 
    super(props); 
    this.state = { 
     dataSource: new ListView.DataSource({ 
     rowHasChanged: (row1, row2) => row1 !== row2, 
     }), 
    }; 

    const user = firebase.auth().currentUser; 
    if (user != null) { 
     this.itemsRef = this.getRef().child(`Stores/${user.uid}/`); 
    } else { 
     Alert.alert('Error', 'error!'); 
    } 
    this.connectedRef = firebase.database().ref('.info/connected'); 
    this.handleValue = this.handleValue.bind(this) // here added 
    } 

希望しても問題は解決します。

+0

私はこれが私の(確かに不確かな)答えに欠けていた魔法の妖精だと思います。関数のバインディングは、イベントリスナーの切り替えが機能していない可能性が非常に高いです。 –

1

あなたはすべてのイベントハンドラをオフにしていません。

'value'イベントのイベントハンドラを、listenForItems()内のitemsRefオブジェクトに作成します。そのイベントハンドラはsetState()を呼び出します。この特定のイベントハンドラはオフにされていません。つまり、後続のすべてのデータベースイベントが古い(マウントされていない)コンポーネントのsetState()をコールしようとするコールバック関数を呼び出します。

あなたは以下のようなものを、componentWillUnmount()でのイベントハンドラのすべてのスイッチをオフにする必要があります

componentWillUnmount() { 
    this.itemsRef.off(); 
    this.connectedRef.off('value', this.handleValue); 
} 
2

を問題は、彼らが言及しているものだったが、無ソリューションを提供します。 しばらくして、いくつかの外部の助けを借りて、これが私の問題を解決しました。 リスナーを削除するだけです。

componentWillUnmount() { 
    this.itemsRef.off(); // this line 
    this.connectedRef.off('value', this.handleValue); 
    } 
+0

申し訳ありませんが、André - 私はおそらくこのコードスニペットを私の回答に含めるべきでした!私はあなた自身の解決策を見つけてうれしいです。 –

関連する問題

 関連する問題