【问题标题】:How to properly delete object subfields when dispatching a new redux action?调度新的 redux 操作时如何正确删除对象子字段?
【发布时间】:2020-11-11 09:23:24
【问题描述】:

我想知道在 redux 操作中删除嵌套字段的正确方法是什么。例如,我有这样的代码:

const SUBSCRIBE = 'SUBSCRIBE';
const UNSUBSCRIBE = 'UNSUBSCRIBE';

export default function reducer(state = {}, action) {
  const {
    productName,
    products,
    componentName
  } = action;
  switch (action.type) {
    case UNSUBSCRIBE: {
      if (state[productName]?.[componentName]) {
        const newState = { ...state };
        delete newState[productName][componentName];
        return newState;
      } else {
        return state;
      }
    }
    default:
      return state;
  }
}


export function unsubscribe(productName, componentName) {
  return {
    type: UNSUBSCRIBE,
    productName,
    componentName
  };
}

UNSUBSCRIBE 操作中,我删除了newState[productName][componentName] 字段,但是这也会删除处于“旧”状态的字段。所以理论上,如果有其他动作使用这个字段,它可能会因为状态发生变化而丢失。我是否应该将旧状态深度复制到newState,然后删除newState[productName][componentName]

【问题讨论】:

    标签: javascript reactjs redux


    【解决方案1】:

    您可以选择以下两种方法之一:

    1. 创建productName 状态的副本并从该副本中删除componentName
    if (state[productName]?.[componentName]) {
      const newProductState = { ...state[productName] };
      delete newProductState[componentName];
      return {
        ...state,
        [productName]: newProductState
      };
    } else {
      return state;
    }
    
    1. 您可以将componentName 标记为未定义而不是删除(我个人更愿意这样做)
    if (state[productName]?.[componentName]) {
      return {
        ...state,
        [productName]: {
          ...state[productName],
          [componentName]: undefined,
        },
      };
    } else {
      return state;
    }
    

    【讨论】:

    • 但是使用delete删除该属性是否有风险? redux 操作无论如何都不能并行执行,对吗? (因为 Javascript 是单线程的)
    • @hitchhiker 当您复制对象的一部分并从该部分复制 delete 时,例如示例#1,没有危险。可以同步和异步调度操作,但这并不重要。 Redux 操作,无论它们被分派的方式如何,都由定义为同步的 reducer 函数处理。
    • 那么为什么最好不要在你的例子中使用delete
    • @hitchhiker 我相信,您的意图是清理未使用的属性以优化内存。但是,delete 与内存优化无关。要在 JS 中从内存中删除一个对象,所有对它的引用都必须被删除或超出范围。请参阅this answer
    • @hitchhiker 通常是的。但这取决于您的选择器。如果他们依赖于整个状态对象(对它的引用发生了变化),则应该反映变化
    猜你喜欢
    • 2022-01-24
    • 2015-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-22
    相关资源
    最近更新 更多