为什么Array.indexOf()可以在一个redux动作上正常工作,而在另一个redux上却不能正常工作? (相同的减速器)

问题描述 投票:0回答:2
var tags = ['tag1', 'tag2', 'tag3', 'tag4', 'tag5',
            'tag6', 'tag7', 'tag8', 'tag9', 'tag0'];

var selectedTags = [];

const tagsReducer = (state={}, action) => {
    var tagIndex = '';
    if(action.type==="ADD_TAG") {                     //this if statement works as expected
        tagIndex = tags.indexOf(action.payload);
        selectedTags.push(tags[tagIndex]);
        tags.splice(tagIndex, 1);
        return {tags, selectedTags};    
    }
    if(action.type==="REMOVE_TAG"){                          //this doesn't
        tagIndex = selectedTags.indexOf(action.payload);
        console.log(selectedTags);                            //prints the expected array
        console.log(action.payload);                          //prints the expected string
        console.log(tagIndex);                                //prints -1 (doesn't find the string)
        console.log(typeof(selectedTags));                    //prints object
        console.log(typeof(action.payload));                  // prints string
        tags.push(selectedTags[tagIndex]); 
        selectedTags.splice(tagIndex, 1);

        return {tags, selectedTags};
    }
    return {tags, selectedTags}
}

字符串对数组项之一进行运算,但是indexOf()函数仍返回-1。这很混乱,因为第一个操作可以正常运行,但是第二个则不能。有什么建议么?

javascript arrays reactjs redux indexof
2个回答
2
投票

字符串运算数组项之一,但indexOf()函数仍返回-1

没有匹配调用indexOf时的数组项之一,因为如果匹配,则indexOf会找到它。indexOfisn't broken

因此有两种一般可能性:

  1. 数组中的字符串看起来应该匹配,但与payload中的字符串略有不同。可能并不明显的不同方式:

    • 其中一个(数组中的一个或payload中的一个)在开头或结尾处可能有空格,等等。
    • 其中一个可能在大小写上略有不同。
    • 它们的字符可能略有不同,很容易混淆,例如ç
    • [数组中的条目中可能包含逗号,例如"thisTag,thatTag",尽管看起来像"thatTag"在数组中,但如果您去看,当然不会匹配"thatTag"
    • 其中一个可以是String对象,另一个是字符串基元; String对象和字符串基元彼此不是===,并且indexOf使用===测试。
  2. 自调用selectedTags以来,该字符串不在indexOf数组中,即使在控制台中看起来像它。这是因为this feature of consoles

要弄清楚,请在indexOf行上设置一个断点,当它被击中时,查看payload中的字符串和selectedTags中的字符串(如果存在,如果没有,则为控制台)事情)。您会发现some差异。


0
投票

存在多个问题。您正在尝试修改外部变量。这不纯。 redux的第一条规则,不要添加副作用来修改外部数据。它必须是纯净的。输出应该是输入数据上的已处理数据。下面是示例代码。您可以稍后对其进行优化。

var tags = [
  "tag1",
  "tag2",
  "tag3",
  "tag4",
  "tag5",
  "tag6",
  "tag7",
  "tag8",
  "tag9",
  "tag0"
];

var selectedTags = [];

const tagsReducer = (state = { tags, selectedTags }, action) => {
  var tagIndex = -1;
  if (action.type === "ADD_TAG") {
    //this if statement works as expected
    tagIndex = state.tags.indexOf(action.payload);
    const data = state.tags[tagIndex];
    return {
      tags: state.tags.filter(x => x !== data),
      selectedTags: state.selectedTags.concat(data)
    };
  }
  if (action.type === "REMOVE_TAG") {
    //this doesn't

    tagIndex = state.selectedTags.indexOf(action.payload);
    const data = state.tags[tagIndex];

    if (data)
      return {
        tags: state.tags,
        selectedTags: selectedTags.filter(x => x !== data)
      };
  }
  return state;
};

我试图创建stackblitz,也尝试起草。https://stackblitz.com/edit/redux-playground-twrxyy?file=index.js

© www.soinside.com 2019 - 2024. All rights reserved.