【问题标题】:useReducer dispatch executing twiceuseReducer 调度执行两次
【发布时间】:2020-07-23 06:08:08
【问题描述】:

我不明白为什么会这样。由于在 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 而不是原始数据类型(数字),则可以正常工作。即,即使调用了两次 dispatch,也只会删除一项。

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

我在这里遗漏了什么吗?到底发生了什么?

【问题讨论】:

  • item.index = .... 正在改变状态。
  • 它是如何改变状态的?在进行编辑之前,使用扩展运算符将数组复制到新数组中。
  • "数组被复制到一个新的"是部分正确的,它是一个浅拷贝。
  • ^^^ 项目仍然引用状态数组中的对象

标签: javascript reactjs react-hooks


【解决方案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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

      猜你喜欢
      • 2022-01-11
      • 2020-07-19
      • 1970-01-01
      • 2012-09-23
      • 1970-01-01
      • 1970-01-01
      • 2021-02-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多