2016-11-11 38 views
1

對於我正在編寫的反應組件,我正在使用redux來管理組件的狀態。我之前沒有真正使用過redux,所以我遇到了一些我寫過的減速器的問題。我的反應組件中的一個方法使得一個http請求通過一個簡單的動作函數將數據分派給reducer。然而,我爲這個reducer寫了另一個動作來從狀態中刪除條目,但是每當我使用這個動作時,reducer都會返回一個空數組。任何幫助表示讚賞。redux reducer在過濾狀態時返回空數組

減速器

export function Weeklystate(state=[], action){ 
    switch(action.type){ 
     case 'ADD_PROVIDER': 
      return [...state, action.arr]; 

     case 'REMOVE_PROVIDER': 
      const newstate = [...state]; 

      return newstate.filter((provider) => provider[0].full_name.toLowerCase().indexOf(action.str) === -1); 

     default: 
      return state; 
    } 
} 

actions.js

export function addProvider(arr){ 
    return { 
     type: 'ADD_PROVIDER', 
     arr 
    }; 
} 

export function removeProvider(str){ 
    return { 
     type: 'REMOVE_PROVIDER', 
     str 
    }; 
} 

組件方法

getData(){ 
    const { url, queries } = this.state; 
    let data_arr = []; 

    const que = queries.map(function(query){ 
     let postquery = { 
      full_name: query.name, 
      date_start: query.startdate, 
      date_end: query.enddate 
     }; 

     return axios.post(url, postquery); 
    }); 

    axios.all(que).then((responses) => { 
     responses.forEach((response) => { 
      this.props.addProvider(response.data); 
     }); 
    }); 
} 

componentWillMount(){ 
    this.getData(); 
    this.props.removeProvider('Example Name here'); 
    const { rawdata } = this.props; 

    return console.log(this.props); 
} 

個MaptoProps功能

function mapStateToPropsBETA(state){ 
    return { 
     rawdata: state.rawdata, 
     parseddata: state.parseddata 
    }; 
} 

function mapDispatchtoProps(dispatch){ 
    return bindActionCreators({ 
     addProvider: addProvider, 
     removeProvider: removeProvider 

    }, dispatch); 
} 

export default connect(mapStateToPropsBETA, mapDispatchtoProps)(Weekly_Beta); 

stores.js

const WeeklyStore = createStore(reducer); 

WeeklyStore.subscribe(() => { 
    console.log(WeeklyStore.getState()); 
}); 

export default WeeklyStore; 

樣本數據

[ 
[ 
    { 
     first_name: "First Name Here...", 
     last_name: "Last Name Here...", 
     full_name: "Full Name Here", 
     date: "2016-01-17", 
     charges: { 
      cosmetic: 25000.00, 
      medical: 25000.00, 
      total: 50000.00 
     }, 
     payments: 75000.00, 
     appointments: 99, 
     pk: 5 
    }, 
    { 
     first_name: "First Name Here...", 
     last_name: "Last Name Here...", 
     full_name: "Full Name Here", 
     date: "2016-01-24", 
     charges: { 
      cosmetic: 25000.00, 
      medical: 25000.00, 
      total: 50000.00 
     }, 
     payments: 75000.00, 
     appointments: 99, 
     pk: 5 
    }, 
], 
[ 
{ 
    first_name: "First Name Here...", 
    last_name: "Last Name Here...", 
    full_name: "Full Name Here", 
    date: "2016-01-17", 
    charges: { 
     cosmetic: 25000.00, 
     medical: 25000.00, 
     total: 50000.00 
    }, 
    payments: 75000.00, 
    appointments: 99, 
    pk: 5 
}, 
{ 
     first_name: "First Name Here...", 
     last_name: "Last Name Here...", 
     full_name: "Full Name Here", 
     date: "2016-01-24", 
     charges: { 
      cosmetic: 25000.00, 
      medical: 25000.00, 
      total: 50000.00 
     }, 
     payments: 75000, 
     appointments: 99, 
    pk: 5 
    }, 
] 
]; 

UPDA TE

我做了一些測試,並得到了一些奇怪的結果。我在控制檯內部執行了相同的代碼,並且我的一切都運行良好。但是,reducer仍然返回一個空數組。

Google Chrome console screenshot


更新#2

一些進一步的疑難解答我想我可能會是什麼引起的狀態不當寫一個更好的想法後。我能夠讓擴散操作員工作,因此數據不可變性在這一點上不是什麼大問題。

但是,在排除故障時,我偶然發現了兩件事。當redux狀態改變時,保持我的redux狀態的組件道具不會被更新。爲了證實這一點,我使用了subscribe方法來給我狀態,每當一個動作被調度時。 rawdata的字段填充了我在redux狀態下查找的數據,但是,數據未被推送到等效組件prop。

我注意到的第二件事是REMOVE_PROVIDER操作不會調度,因爲訂閱方法不會在控制檯中報告任何內容。我不知道爲什麼會發生這種情況,但我認爲filter也許可能是原因,因爲每當我嘗試調度動作時,redux狀態都保持不變。

在這一點上我相信我遇到的問題更多的是react-redux問題,而不是reducer本身的問題。我也冒着更新我的代碼片斷的反應,以反映我所看到的。

日誌從道具的反應成分enter image description here

+0

你不能改變狀態。需要創建一個'newState'然後返回它。 – Ryan27

+0

那我該如何處理呢?我知道很多人建議使用傳播運算符來幫助實現這一目標,但由於某種原因,我無法讓它爲我工作。請注意,我對redux也很新。 – TechEmperor95

+0

設置變量'let newState = state;'然後將過濾器應用於'newState',並返回'newState'。你在正確的軌道上。 – Ryan27

回答

0

如果你的例子是準確的,那麼就改變REMOVE_PROVIDER情況下

case 'REMOVE_PROVIDER': 
      return newstate.filter((provider)=> provider[0].full_name.indexOf(action.data) === -1); 
:從終極版商店 enter image description here

日誌條目

因爲它寫在你的問題,th e篩選器將返回名稱爲「此處爲示例名稱」的所有提供者。這不關他們。您希望得到相反的結果,即返回名稱與輸入名稱不匹配的所有提供者。

+0

我在這個例子中做了同樣的事情,但它仍然返回空 – TechEmperor95

0
  1. 首先,您的ADD_PROVIDER直接突變所述state,加入newstate = state不復制狀態陣列,因爲它僅創建到的狀態的基準。

  2. 對於你的ADD_PROVIDER什麼是action.data?根據你的行爲,本身已經是一個數組,但你用另一個數組符號包裝它,你的狀態變成了數組數組。 -____-?

  3. 正如其他答案建議,您的REMOVE_PROVIDER邏輯是錯誤的,你保留所有prodiver s的全名有action.data

要解決,你的減速應該是:

export function Weeklystate(state=[], action){ 
    switch(action.type){ 
    case 'ADD_PROVIDER': 
     return [...state, action.data]; // this returns a new array 

    case 'REMOVE_PROVIDER': 
     // this will keep provider whose full_name does not have action.data 
     return state.filter((provider)=>provider[0].full_name.indexOf(action.data.full_name) === -1); 

    default: 
     return state; 
    } 
} 

正如我的第二點建議,我不知道你怎麼想你的狀態的樣子,所以相應的修正。通過這段代碼,我假設ADD_PROVIDER action.data是一個包含1個元素的數組。

+0

除了在'ADD_PROVIDER'的解決方案中,您正在使用spread運算符來克隆狀態。我已經試過這樣做,它不起作用。 – TechEmperor95

相關問題