为什么 filter 方法的工作方式似乎与此待办事项应用程序中的 splice 工作方式不同?

Why does the filter method not seem to work the same way as splice does in this todo app?

我有一个 JS 待办事项应用程序,具有以下功能:

这是将 id 传递到事件侦听器以删除待办事项的函数的一部分

removeButton.addEventListener('click', function () {
                removeTodo(todo.id)
                renderTodos(todos, filters)
            })

此函数删除了待办事项 - 我使用了 2 种方法,findIndex 方法效果很好,它删除了待办事项并很好地呈现新的待办事项 - 我认为我评论过的过滤器方法也可以,但它不起作用't,它确实删除了待办事项,但它不会自动更新浏览器中的列表,除非我刷新页面,而 splice 会自动更新,为什么会这样?会不会是在 renderTodos 开始读取列表之前等待更新本地存储?请注意,在不起作用的示例中,我将 newTodos 传递给保存函数,我只是将其更改为 todos 作为拼接方式。

const removeTodo = function (id) {
const todoIndex = todos.findIndex(function (todo) {
    return todo.id === id
})

if (todoIndex > -1) {
    todos.splice(todoIndex, 1)
}
// newTodos = todos.filter(function (todo) {
//     return todo.id !== id
// })
saveTodos(todos)
}

待办事项列表保存在本地存储

const saveTodos = function (todos) {
    localStorage.setItem('todos', JSON.stringify(todos))
}

这里是渲染函数供参考

const renderTodos = function (todos, filters) {
        const filteredTodos = todos.filter(function (todo) {
            const searchTextMatch = todo.text.toLowerCase().includes(filters.searchText)
            const hideCompletedMatch = !filters.hideCompleted || !todo.completed
            return searchTextMatch && hideCompletedMatch
        })
            
        const todosLeft = filteredTodos.filter(function (todo) {
            return !todo.completed
        })
        document.querySelector('#todos').innerHTML = ''
        document.querySelector('#todos').appendChild(generateSummaryDom(todosLeft))

        filteredTodos.forEach(function (todo) {
            document.querySelector('#todos').appendChild(generateTodoDom(todo))
        })
}

重新赋值一个变量没有side-effects;重新分配一个标识符对别处的标识符没有影响。正在做

  newTodos = todos.filter(function (todo) {
    return todo.id !== id
  })
  saveTodos(todos)
}

表示您已将一些结果放入 newTodos 而未对其进行任何其他操作。它不会被存储(或呈现,尽管未显示您的呈现方式)。

传递新的过滤待办事项,并从那里渲染(无论您如何进行渲染)- 不要忘记声明您的变量。

  const newTodos = todos.filter(function (todo) {
    return todo.id !== id
  })
  saveTodos(newTodos);
  renderTodos(newTodos);

同时将 renderTodos 从即时侦听器回调中取出。

splice() 改变您随后渲染的 todos 数组,而 filter() return 是您未使用的新数组。

要使其与 filter() 一起使用,您需要 return 移除函数中的 newTodos 并呈现 returned 数组,而不是原始 todos数组。

removeButton.addEventListener('click', function () {
  const newTodos = removeTodo(todo.id);
  saveTodos(newTodos)
  renderTodos(newTodos, filters);
})

const removeTodo = function (id) {
  return todos.filter(todo => todo.id !== id)
}

const saveTodos = function (todos) {
  localStorage.setItem('todos', JSON.stringify(todos))
}