【问题标题】:Trying to do a filter method on an object尝试对对象执行过滤器方法
【发布时间】:2020-08-01 16:34:50
【问题描述】:

我正在尝试删除待办事项,我想从具有特定 ID 的对象“byIds”中删除该项目。 它就像数组的过滤器,但对象的过滤器。 我不知道有什么复杂的希望得到帮助我相信它很愚蠢

import { ADD_TODO, TOGGLE_TODO, DELETE_TODO } from "../actionTypes";

const initialState = {
  allIds: [],
  byIds: {},
};

export default function (state = initialState, action) {
  switch (action.type) {
    case ADD_TODO: {
      const { id, content } = action.payload;
      return {
        ...state,
        allIds: [...state.allIds, id],
        byIds: {
          ...state.byIds,
          [id]: {
            content,
            completed: false,
          },
        },
      };
    }
    case TOGGLE_TODO: {
      const { id } = action.payload;
      return {
        ...state,
        byIds: {
          ...state.byIds,
          [id]: {
            ...state.byIds[id],
            completed: !state.byIds[id].completed,
          },
        },
      };
    }
    // of course its toggling but it doesn't even get there
    case DELETE_TODO: {
      const { id } = action.payload;
      return {
        ...state,
        allIds: state.allIds.filter((todo) => todo !== id),
        byIds: state.byIds.filter((todo) => todo !== id),
      };
    }
    default:
      return state;
  }
}

{
  todos: {
    allIds: [
      1,
      2,
      3,
      4
    ],
    byIds: {
      '1': {
        content: 'Test1',
        completed: false
      },
      '2': {
        content: 'Test2',
        completed: false
      },
      '3': {
        content: 'test3',
        completed: false
      },
      '4': {
        content: 'test4',
        completed: false
      }
    }
  },
  visibilityFilter: 'all'
}

对于要求我控制台记录 byIds 的人希望对我有所帮助

【问题讨论】:

  • 你能分享console.log(byIds)的数据形状吗?添加到帖子中。
  • Redux 对于这个问题来说是不必要的,如果你把它抽象出来做出反应会更容易,或者更简单的是 JS。
  • @NicolasHevia 清除标签
  • @BARNOWL 我做到了希望得到帮助,我只想删除一个待办事项
  • 以下任何答案有帮助吗?

标签: javascript reactjs


【解决方案1】:

您需要的是遍历byids 对象的keys 并只取您需要的那些。

case DELETE_TODO: {
  const { id } = action.payload;
  let newObj = {}

  Object.keys(state.byIds).forEach(function(key) {
    if (key !== id) {
      newObj[key] = state.byIds[key]
   }
  });
  return {
    ...state,
    allIds: state.allIds.filter((todo) => todo !== id),
    byIds: newObj 
  };
}

如果您的 id 不是字符串而是数字,则需要检查 key != id 而不是 key !== id

【讨论】:

  • @Ethanolle 这有帮助吗?
  • 第 42 行:'byids' 未定义 no-undef 第 44 行:'byids' 未定义 no-undef
  • @BARNOWL 老实说,我喜欢解构的另一个答案。我的解决方案是经典的 js,其他的是 ES6 风格:)
  • 第 42 行:'byIds' 未定义 no-undef 第 44 行:'byIds' 未定义 no-undef Sanme Probleme
  • 如果我在街上看到你我就给你一个吻,谢谢你这么年轻
【解决方案2】:

您可以在创建新对象时使用其余语法排除 id。

case DELETE_TODO: {
  const { id } = action.payload;
  const { [id]: _, ...restByIds } = state.byIds;
  return {
    ...state,
    allIds: state.allIds.filter((todo) => todo !== id),
    byIds: restByIds,
  };
}

【讨论】:

  • 不错,我不知道这叫rest语法。
  • 不,只是删除我的 allIds 状态而不是 byIds
  • @Ethanolle,你真的试过了吗? restByIds 将包含过滤后的 byIds 对象...
【解决方案3】:

你可以像这样将id分开:

case DELETE_TODO: {
  const id = action.payload.id;
  const { [id]: _, ...filteredState } = state.byIds; 
  // ^ this takes id from state and puts it in variable _,
  // everything else is packed into filteredState

  return {
    ...state,
    allIds: state.allIds.filter((todo) => todo !== id),
    byIds: filteredState,
  };
}

编辑: 任何想知道上述语法的人的额外说明,请参阅以下链接:

Computed Property Names,我们怎么抢[id]

Destructuring assignment,我们如何打包回...filteredState

Awesome comment explaining destructuring

【讨论】:

  • 不,只是删除我的 allIds 状态而不是 byIds
  • 啊,从阅读其他 cmets 看来,它不起作用的原因是因为您将数字作为 action.payload.id 传递,但 byIds 中的键是字符串。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-09-23
  • 2019-07-28
  • 1970-01-01
  • 1970-01-01
  • 2023-01-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多