2016-11-11 158 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

相关问题