繁体   English   中英

redux reducer在过滤状态时返回空数组

[英]redux reducer returns empty array when filtering state

对于我正在编写的反应组件,我正在使用redux来管理组件的状态。 我之前没有真正使用过redux,所以我遇到了一些我写过的reducer的问题。 我的react组件中的一个方法使http请求然后通过一个简单的动作函数将数据分派到reducer。 但是,我为此reducer编写了另一个操作来删除状态中的条目,但每当我使用此操作时,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
  },
 ]
];

更新

我做了一些测试,得到了一些奇怪的结果。 我在chrome的控制台里面执行了相同的代码,我的一切都运行得很好。 但是,reducer仍然返回一个空数组。

谷歌Chrome控制台截图


更新#2

经过一些进一步的故障排除后,我想我可能会更好地了解导致状态写错的原因。 我能够让传播操作员工作,因此数据不变性在这一点上不是问题。

但是,在进行故障排除时我碰巧注意到了两件事。 当redux状态改变时,不会更新保持我的redux状态的组件props。 为了确认这一点,我使用subscribe方法在调度操作时给我状态。 rawdata的字段填充了我在redux状态下查找的数据,但是,数据没有被推送到等效组件prop。

我注意到的第二件事是REMOVE_PROVIDER操作没有调度,因为subscribe方法不会在控制台中报告任何内容。 我不确定为什么会发生这种情况,但我认为filter可能是原因,因为每当我尝试调度动作时,redux状态都保持不变。

在这一点上,我确信我遇到的问题更多的是反应 - 减少问题而不是减速器本身的问题。 我也冒昧地更新我的代码片段以反映我所看到的内容。

反应成分的道具记录 在此输入图像描述

来自redux商店的日志条目 在此输入图像描述

如果您的示例是准确的,那么只需将REMOVE_PROVIDER案例更改为

case 'REMOVE_PROVIDER':
            return newstate.filter((provider)=> provider[0].full_name.indexOf(action.data) === -1);

正如您在问题中所写的那样,过滤器将返回名称为“Example Name Here”的所有提供者。 那不是他们。 您希望相反,即返回名称与输入名称不匹配的所有提供程序。

  1. 首先,您的ADD_PROVIDER正在直接改变state ,添加newstate = state不会复制状态数组,因为它只创建对状态的引用。

  2. 对于你的ADD_PROVIDERaction.data什么? 根据你的动作,它本身已经是一个数组,但你用另一个数组符号包装它,你的状态变成了数组数组。 -____-?

  3. 正如另一个答案建议的那样,你的REMOVE_PROVIDER逻辑是错误的,你要保留其全名具有action.data所有prodiver

要修复,你的减速器应该是:

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个元素的数组。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM