简体   繁体   English

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

[英]redux reducer returns empty array when filtering state

For a react component I'm writing I'm using redux to manage the state of the component. 对于我正在编写的反应组件,我正在使用redux来管理组件的状态。 I haven't really used redux before so I've been running into some issues with one of the reducers i've written. 我之前没有真正使用过redux,所以我遇到了一些我写过的reducer的问题。 One of the methods in my react component makes a http request then dispatches the data to the reducer through a simple action function. 我的react组件中的一个方法使http请求然后通过一个简单的动作函数将数据分派到reducer。 However, I have another action written for this reducer to delete entries from the state, but whenever I use this action the reducer returns a empty array. 但是,我为此reducer编写了另一个操作来删除状态中的条目,但每当我使用此操作时,reducer返回一个空数组。 Any help is appreciated. 任何帮助表示赞赏。

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 : actions.js

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

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

Component methods : 组件方法

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 functions : 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 : stores.js

const WeeklyStore = createStore(reducer);

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

export default WeeklyStore;

sample data : 样本数据

[
 [
  {
      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
  },
 ]
];

UPDATE : 更新

I did some testing and I got some bizarre results. 我做了一些测试,得到了一些奇怪的结果。 I executed the same code inside of the console on chrome and my everything ran just fine. 我在chrome的控制台里面执行了相同的代码,我的一切都运行得很好。 However, the reducer is still returning a empty array. 但是,reducer仍然返回一个空数组。

谷歌Chrome控制台截图


UPDATE #2 : 更新#2

After some further troubleshooting I think I might have a better idea of what's causing the state to write improperly. 经过一些进一步的故障排除后,我想我可能会更好地了解导致状态写错的原因。 I was able to get the spread operator working so data immutability isn't much of an issue at this point. 我能够让传播操作员工作,因此数据不变性在这一点上不是问题。

However, there's two things that I happened to notice when troubleshooting. 但是,在进行故障排除时我碰巧注意到了两件事。 The component props that hold my redux state are not being updated when the redux state changes. 当redux状态改变时,不会更新保持我的redux状态的组件props。 To confirm this I used the subscribe method to give me the state whenever a action is dispatched. 为了确认这一点,我使用subscribe方法在调度操作时给我状态。 The field for rawdata is populated with the data I'm looking for in my redux state, however, the data is not being pushed to the equivalent component prop. rawdata的字段填充了我在redux状态下查找的数据,但是,数据没有被推送到等效组件prop。

The second thing I noticed is that the REMOVE_PROVIDER action isn't dispatching as the subscribe method doesn't report anything back in the console. 我注意到的第二件事是REMOVE_PROVIDER操作没有调度,因为subscribe方法不会在控制台中报告任何内容。 I'm not sure why this is happening, but I think the filter perhaps may be the cause as the redux state remains untouched whenever I try dispatching the action. 我不确定为什么会发生这种情况,但我认为filter可能是原因,因为每当我尝试调度动作时,redux状态都保持不变。

At this point I'm convinced that the problems I'm having are more of react-redux issue rather than being a problem with reducer itself. 在这一点上,我确信我遇到的问题更多的是反应 - 减少问题而不是减速器本身的问题。 I've also taken the liberty of updating my code snippets to reflect what I'm seeing. 我也冒昧地更新我的代码片段以反映我所看到的内容。

log of props from react component : 反应成分的道具记录 在此输入图像描述

log entries from redux store : 来自redux商店的日志条目 在此输入图像描述

If your example is accurate, then just change the REMOVE_PROVIDER case to 如果您的示例是准确的,那么只需将REMOVE_PROVIDER案例更改为

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

As it's written in your question, the filter is returning all providers who have the name "Example Name Here". 正如您在问题中所写的那样,过滤器将返回名称为“Example Name Here”的所有提供者。 That's none of them. 那不是他们。 You want the opposite, that is, to return all of the providers whose names don't match the entered name. 您希望相反,即返回名称与输入名称不匹配的所有提供程序。

  1. Firstly, your ADD_PROVIDER is mutating the state directly, adding newstate = state doesn't copy the state array, as it only creates an reference to the state. 首先,您的ADD_PROVIDER正在直接改变state ,添加newstate = state不会复制状态数组,因为它只创建对状态的引用。

  2. For your ADD_PROVIDER , what is action.data ? 对于你的ADD_PROVIDERaction.data什么? According to your actions, itself is already an array, yet you are wrapping it with another array notation, your state becomes array of arrays of array. 根据你的动作,它本身已经是一个数组,但你用另一个数组符号包装它,你的状态变成了数组数组。 -____-?. -____-?

  3. As the other answer suggested, your REMOVE_PROVIDER logic is wrong, you are keeping all the prodiver s whose fullname has action.data . 正如另一个答案建议的那样,你的REMOVE_PROVIDER逻辑是错误的,你要保留其全名具有action.data所有prodiver

To fix, your reducer should be: 要修复,你的减速器应该是:

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;
    }
}

As my second point suggest, I am not sure how you want your state to look like, so fix accordingly. 正如我的第二点建议,我不确定你希望你的州看起来像什么,所以要相应地修复。 With this code, I assume ADD_PROVIDER action.data is an array with 1 element. 使用此代码,我假设ADD_PROVIDER action.data是一个包含1个元素的数组。

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

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