首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在React中构建一个todo应用程序,使用过滤器,但是需要一种方法来确保“完成”按钮只删除一个任务而不是两个任务。

在React中构建一个todo应用程序,使用过滤器,但是需要一种方法来确保“完成”按钮只删除一个任务而不是两个任务。
EN

Stack Overflow用户
提问于 2022-01-11 18:54:44
回答 1查看 100关注 0票数 1

我刚开始学习react,所以我遵循这个教程https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Client-side_JavaScript_frameworks/React_components创建了一个todo应用程序,然后对它进行了调整,以适应我正在进行的项目的需求。所有事情都按照它应该的方式工作,除了我从关联方删除(完成)事情时,它还从我的主端删除它。我理解为什么会发生这种情况(我的代码中没有两个单独的列表),只是不知道如何在不删除过滤器的情况下修复它。我曾试图为这些任务实现一个单独的列表,但我只是不知道如何完成它。

添加了CodeSandBox以获取更多上下文:https://codesandbox.io/s/hungry-sky-5f482?file=/src/index.js检查任务项,然后查看您在“显示关联任务”中签入的项。问题是在关联方完成一个任务,也可以在“显示所有任务”方面完成任务。

App.js

代码语言:javascript
复制
const FILTER_MAP = {
  All: () => true,
  Associate: task => task.checked 
};
const FILTER_NAMES = Object.keys(FILTER_MAP);

function App(props) {

  const [tasks, setTasks] = useState(props.tasks);
  const [filter, setFilter] = useState('All');

  function toggleTaskChecked(id) {
    const updatedTasks = tasks.map(task => {
      if (id === task.id) {
        return {...task, checked: !task.checked}
      }
      return task;
    });
    setTasks(updatedTasks);
  }

  function completeTask(id) {
    const remainingTasks = tasks.filter(task => id !== task.id);
    setTasks(remainingTasks);
  }

  const taskList = tasks
    .filter(FILTER_MAP[filter])
    .map(task => (
      <Todo
        id={task.id}
        name={task.name}
        checked={task.checked}
        key={task.id}
        toggleTaskChecked={toggleTaskChecked}
        completeTask={completeTask}
      />
    ));

  const filterList = FILTER_NAMES.map(name => (
    <FilterButton
    key={name}
    name={name}
    isPressed={name === filter}
    setFilter={setFilter}
  />
  ));

  function addTask(name) {
    const newTask = { id: "todo-" + nanoid(), name: name, checked: false };
    setTasks([...tasks, newTask]);
  }

  return (
    <div className="app">
      <h1 className = "tasks-header">Task Tracker</h1>
      <Form addTask={addTask}/>
      <div className="list-buttons">
        {filterList}
      </div>
      <ul
        role="list"
        className="todo-list"
        aria-labelledby="list-heading"
      >
        {taskList}
      </ul>
    </div>
  );

}

export default App

Todo.js

代码语言:javascript
复制
export default function Todo(props) {

  return (
    <li className="todo stack-small">
      <div className="c-cb">
        <input id={props.id} 
        type="checkbox" 
        defaultChecked={props.checked}
        onChange={() => props.toggleTaskChecked(props.id)} 
        />
        <label className="todo-label" htmlFor="todo-0">
          {props.name}
        </label>
      </div>
      <div className="btn-group">
        <button type="button" 
        className="complete-button"
        onClick={() => props.completeTask(props.id)}
        >
          Complete 
        </button>
      </div>
    </li>
  );
  }

index.js

代码语言:javascript
复制
const DATA = [
  { id: "todo-0", name: "Brush Teeth", checked: false },
  { id: "todo-1", name: "Make Dinner", checked: false },
  { id: "todo-2", name: "Walk Dog", checked: false },
  { id: "todo-3", name: "Run Reports", checked: false },
  { id: "todo-4", name: "Visit Mom", checked: false },
  { id: "todo-5", name: "Aerobics", checked: false },
  { id: "todo-6", name: "Project", checked: false },
  { id: "todo-7", name: "Lecture", checked: false },
  { id: "todo-8", name: "Have Lunch", checked: false }
];

ReactDOM.render(
  <React.StrictMode>
    <App tasks={DATA}/>
  </React.StrictMode>,
  document.getElementById('root')
);

FilterButton.js

代码语言:javascript
复制
function FilterButton(props) {
    return (
      <button
        type="button"
        className="toggle-btn"
        aria-pressed={props.isPressed}
        onClick={() => props.setFilter(props.name)}
      >
        <span className="visually-hidden">Show </span>
        <span>{props.name}</span>
        <span className="visually-hidden"> Tasks</span>
      </button>
    );
  }

export default FilterButton;
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-01-11 19:46:55

我们有三个布尔字段:checkedcompletedcompletedAssoc

代码语言:javascript
复制
  {
    id: "todo-0",
    name: "Brush Teeth",
    checked: false,
    completed: false,
    completedAssoc: false
  },

过滤器的工作方式如下:

代码语言:javascript
复制
  const FILTER_MAP = {
    All: (task) => !task.completed,
    Associate: (task) => task.checked && !task.completedAssoc
  };

以及最后在completeTaskaddTask中的变化

代码语言:javascript
复制
  function completeTask(id) {
    const complField = filter === "All" ? "completed" : "completedAssoc";
    const updatedTasks = tasks.map((task) =>
      id === task.id ? { ...task, [complField]: true } : task
    );
    setTasks(updatedTasks);
  }

  function addTask(name) {
    const newTask = {
      id: "todo-" + nanoid(),
      name: name,
      checked: false,
      completed: false,
      completedAssoc: false
    };
    setTasks([...tasks, newTask]);
  }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70672024

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档