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

Why is Array.indexOf() working correctly with one redux action but not with another? (same reducer)

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() 函数仍然 returns -1。这很令人困惑,因为第一个动作工作正常,但第二个动作却没有。有什么建议么?

string mathes one of the array items, but the indexOf() function still returns -1

与您调用 indexOf 时的数组项之一匹配,因为如果匹配,indexOf 会找到它。 indexOf isn't broken.

所以剩下两种一般可能性:

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

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

为了弄清楚,在 indexOf 行设置一个断点,当它被击中时,查看 payload 中的字符串和 selectedTags 中的字符串(如果它在那里- 如果不是,那就是控制台的事情)。您会发现 一些 差异。

存在多个问题。您正在尝试修改外部变量。这不是纯粹的。 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