无参数重新分配、linter 规则、React、打字稿

No-param-reassign, linter rules, React, typescript

我的 linter 欺负我。

我创建了一个函数,将任务 completed 设置为 !completed,id 作为参数

数据如下所示:

const lists = [
    {
      id: 'todo-3',
      name: 'Example 3',
      tasks: [{ name: 'task', completed: true, id: "Un" },{ name: 'task2', completed: true, id: "Deux" },{ name: 'task3', completed: true, id: "Trois" }]
    }
    {
      id: 'todo-4',
      name: 'Example 5',
      tasks: [{ name: 'task', completed: true, id: "Un" },{ name: 'task2', completed: true, id: "Deux" },{ name: 'task3', completed: true, id: "Trois" }]
    }
  ]

起初,我做了一个这样的函数,它可以工作,但 linter 不喜欢它。

  const toggleTask = (listId: string, taskId: string) => {
    const newListsToggled = lists.map((listItem) => {
      if (listItem.id === listId) {
        listItem.tasks.map((task) => {
          if (task.id === taskId) {
            task.completed = !task.completed;
          }
          return task;
        });
      }
      return listItem;
    });

    
  };

"task.completed = !task.completed" 这部分给了我无参数重新分配错误所以我尝试了另一个函数:

  const toggleTask = (listId: string, taskId: string) => {
    const newListsToggled = lists.map((listItem) => {
      if (listItem.id === listId) {
       return  listItem.tasks.map((task) => {
         if (task.id === taskId) {
            return {...task, completed: !task.completed}
            }
          return task;
          }
        );
      }
      return listItem;
    });
   
   console.log('testtoggle',newListsToggled)
  };

  toggleTask('todo-3','Deux')

这个不是 return 整个数组,lists.namelists.id 部分都没有了。

在不绕过linter的情况下,有没有办法解决这个功能?

This one doesn't return the whole array, the lists.name and lists.id part are gone

要解决此问题,您可以使用与任务相同的对象传播技巧,而不是返回 return listItem.tasks.map(...)

if (listItem.id === listId) {
  return {
    ...listItem,
    tasks: listItem.tasks.map(...)
  }
}

警告是由于您在 .map(task => ... ) 中修改了 task(然后返回它之前)而触发的。您使用地图的方式对输入集合 有副作用。这可能是故意的,也可能是无关紧要的,但它仍在发生。

.map()的目的通常是为每个输入object/value生成一个新的结果object/value。你应该(几乎)永远不要改变你正在做的输入值,你应该只生成输出值。

如果你真的想修改输入值,最好使用.forEach代替:

if (listItem.id === listId) {
   listItem.tasks.forEach((task) => {
      if (task.id === taskId)
         task.completed = !task.completed;
   }
}
return listItem;

这可以结合 .filter 而不是 if:

if (listItem.id === listId) {
   listItem.tasks
      .filter(task => task.id === taskId)
      .forEach(task => task.completed = !task.completed);
}
return listItem;

或者如果您知道匹配任务不会超过 1 个,那么您可以使用 .find:

if (listItem.id === listId) {
   var task = listItem.tasks.find(task.id === taskId);
   if (task) task.completed = !task.completed;
}
return listItem;