2015-09-13 73 views
2

我正在使用React和ReFlux的項目。目前我只有一個ReFlux商店:SubscriptionStore.js。它包含用戶訂閱的簡單詳細信息,包括嵌套的對象數組,其中包含附加到其訂閱的每個「標題」附近的詳細信息。刪除嵌套狀態的項目會導致在DOM中刪除不正確的項目

下面是一個簡單的數據背後擊穿SubscriptionStore.js

{ 
    hasThisSubcription: 0 
    hasThatSubscription: 1 
    nextPeriodStart: "2015-10-12" 
    nextYearStartDate: "2016-09-12" 
    accountTitles: [{ 
     id: "1" 
     title: "The Name" 
     createdDate: "2015-09-12 16:17:08" 
    }, { 
     id: "2" 
     title: "Another Name" 
     createdDate: "2015-09-12 16:17:08" 
    }, { 
     id: "3" 
     title: "Yet Another Name" 
     createdDate: "2015-09-12 16:17:08" 
    }] 
} 

我有一個陣營組件,允許用戶更新現有標題的名稱,添加新的標題或刪除標題。添加和重命名進行得很順利,但刪除操作不當,我相信這是因爲我還沒有完全掌握React/ReFlux。

下面是這個主要成分的相關代碼:

var React = require('react') 
var Reflux = require('reflux') 
var SubscriptionActions = require('../../stores/SubscriptionActions.js') 
var SubscriptionStore = require('../../stores/SubscriptionStore.js') 

module.exports = React.createClass({ 

    mixins: [ 
     Reflux.connect(SubscriptionStore, 'subscriptions') 
    ], 

    /** 
    * Add new title 
    * @param {number} id The Title ID 
    */ 
    addTitle() { 
     SubscriptionActions.addNewTitle() 
    }, 

    /** 
    * Remove Title from state using on ID 
    * @param {number} id The Title ID 
    */ 
    removeTitle(id) { 
     SubscriptionActions.removeNewTitle(id) 
    }, 

    /** 
    * Update Title title using ID 
    * @param {number} id The Title ID 
    * @param {string} value The new title 
    */ 
    saveTitle(id, value) { 
     SubscriptionActions.updateNewTitle(id, value) 
    }, 

    render() { 

     // Check for Title subscriptions and create an editable field for each 
     var theTitles = [] 
     for (var i = 0; i < this.state.subscriptions.accountTitles.length; i++) { 
      theTitles.push(
       <EditableCapsule 
        key = {i} 
        ref = {'title' + i} 
        removable = {i === 0 ? false : true} 
        labelValue = '' 
        clickToRemove = {this.removeTitle.bind(this, i)} 
        primaryAction = {this.saveTitle.bind(this, i)} 
       /> 
      ) 
     } 

     return (
      <div> 
       <ScrollArea ref='scrollArea'> 
        {theTitles} 
       </ScrollArea> 
      </div> 
     ) 
    } 
}) 

和代碼SubscriptionStore.js的相關位:

removeTitle(id) { 
    this.subscriptions.accountTitles = _.without(this.subscriptions.accountTitles, _.findWhere(this.subscriptions.accountTitles, { id: id })); 
    this.trigger(this.subscriptions) 
} 

的問題

無論哪個標題我點擊刪除,它始終是最後標題th在被刪除。如果我在this.subscriptions.accountTitles內容之前和之後吐出一個內容,它會顯示確實正在從數據中刪除正確的對象,但React正在渲染這些元素,就好像它始終是最後一個被刪除的項目一樣。

任何想法可能發生什麼?

回答

3

不使用<EditableCapsule key = {i} ...:中key整點是要一個唯一的標識符的確切元素反應與合作更新,刪除的目的等

其在一些陣列位置說絕對沒有關於元素本身,所以:第一更改爲正確的密鑰:

... 

render: function() { 
    var accountTiles = this.state.subscriptions.accountTitles; 
    var tileset = accountTiles.map(this.buildTiles); 
    return <ScrollArea ref='scrollArea'>{ tileset }</ScrollArea>; 
}, 

buildTiles: function(tile, position) { 
    var identifier = tile.title + title.id; 
    return (
    <EditableCapsule 
     key = { identifier } 
     ref = { identifier } 
     removable = { position !== 0 } 
     labelValue = '' 
     clickToRemove = { this.removeTitle.bind(this, tile) } 
     primaryAction = { this.saveTitle.bind(this, tile) } 
    />; 
); 
}, 
... 

請注意,我們不刪除基於陣列現在的位置了,無論是。我們將根據瓷磚本身進行移除。原因很明顯。

+0

非常感謝您的回覆。那麼你能告訴我,我如何更新'SubscriptionStore.js'中的'removeTitle'函數來使用你傳入的應用程序實例而不是id? –

+0

你也可以傳入id,重點是* not *傳入數組的位置,這沒有任何意義,但要傳入一個實際屬於你的標題的東西。所以如果你想傳入'tile.id',那也可以。只要你記得從基於該id的數組*中刪除它,通過在removale函數內使用類似'accountTiles:accountTiles.filter(function(v){return v.id!== removeId;})' –

+0

太棒了。說得通。非常感謝! –