useReducer调度执行两次

时间:2020-07-23 06:08:08

标签: javascript reactjs react-hooks

我不明白为什么会这样。由于在react中启用了严格模式,因此该函数执行两次。因此,它不会删除两个项目,而是删除两个项目,一个在第一轮,第二个在下一轮。

const deleteItem = (state, index) => {
    // index is a number
       
    let indexCounter = 0;
    let tempArray = [...state.todos];

    const newTodos = tempArray.filter(item => {
        if (item.index === index) {
            return false;
        }
        item.index = indexCounter++;
        return true;
    });

    return {
        ...state,
        todos: newTodos,
        nextIndex: indexCounter
    };   
}

但是,如果我使用Set而不是原始数据类型(数字),则可以正常工作。也就是说,即使调度被调用了两次,也只会删除一项。

const deleteItem = (state, set) => {

    const newSet = new Set(set);
    
    let indexCounter = 0;
    let tempArray = [...state.todos];

    const newTodos = tempArray.filter(item => {
        if (newSet.has(item.index)) {
            newSet.delete(item.index);
            return false;
        }
        item.index = indexCounter++;
        return true;
    });

    return {
        ...state,
        todos: newTodos,
        nextIndex: indexCounter
    };
    
}

我在这里想念什么吗?到底是什么情况?

2 个答案:

答案 0 :(得分:1)

您正在突变影响下一个动作的状态。

// Is a shallow copy
let tempArray = [...state.todos];

const newTodos = tempArray.filter((item) => {
  if (item.index === index) {
    return false;
  }
  // State mutation
  item.index = indexCounter++;
  return true;
});

相反,您需要进行深度复制或使用Redux文档中提到的Immutable Update Pattern

答案 1 :(得分:0)

我已经更新了代码。现在工作正常。希望它是正确的。

const deleteItem = (state, index) => {

    let indexCounter = 0;

    const tempArray = state.todos.filter(item => {
        return index !== item.index;
    });

    const newTodos = [];
    tempArray.forEach((item) => {
        newTodos.push({...item, index: indexCounter++});
    })

    return {
        ...state,
        todos: newTodos,
        nextIndex: indexCounter
    };
    
}