В приложении ToDo при нажатии на дату я получаю список дубликатов задачи. Как это исправить? - PullRequest
0 голосов
/ 04 мая 2020

https://codesandbox.io/s/sleepy-cloud-0fucl?file= / src / components / todo-list / todo-list.jsx

Ccomponent TodoList return TodoListMonth (в папке '/ todo-list-item / todo-list -month '), если ModalMain true, иначе вернуть TodoListDaily (в папке' / todo-list-item / todo-list-day ')

1 Ответ

1 голос
/ 05 мая 2020

Давайте посмотрим на ваш TodoListDaily компонент:

const TodoListDaily = ({
  selectedDate,
  todoData,
  deleteTask,
  setDone,
  modalDetails,
  toggleModalDetails
}) => {
  const existTask = todoData.filter(item => item.date === selectedDate);

  const elements = todoData.map(item => {
    const { id, ...itemProps } = item;

    // ...

    return (
      <li key={id} className="list-group-item">
        {existTask.map(({ id, done, topic, date, month }) => {
          return (
            <div className="todo-list-item-label">
              {/*  ... */}
            </div>
          );
        })}
      </li>
    );
  });

  return (
    <div className="todo-list-wrap">
      <h1 className="title-card">{selectedDate + `th May`}</h1>
      <ul className="list-group todo-list">{elements}</ul>
    </div>
  );
};

Сначала вы фильтруете todoData, а затем перебираете нефильтрованные данные! Так что давайте изменим его на const elements = existTask.map(item => {. Но затем внутри функции карты вы снова перебираете отфильтрованные данные, existTask. Таким образом, если бы у вас было два элемента на одну и ту же дату, было бы отображено четыре записи списка. Вероятно, вы можете просто удалить второй map, поэтому мы получим:

const TodoListDaily = ({
  selectedDate,
  todoData,
  deleteTask,
  setDone,
  modalDetails,
  toggleModalDetails
}) => {
  const existTask = todoData.filter(item => item.date === selectedDate);

  const elements = existTask.map(item => {
    const { id, done, topic, date, month } = item;

    // ...

    return (
      <li key={id} className="list-group-item">
        <div className="todo-list-item-label">
          {/*  ... */}
        </div>
      </li>
    );
  });

  return (
    <div className="todo-list-wrap">
      <h1 className="title-card">{selectedDate + `th May`}</h1>
      <ul className="list-group todo-list">{elements}</ul>
    </div>
  );
};

Я бы также рекомендовал извлечь обратный вызов map в его собственный компонент. Каждый раз, когда JSX возвращается из функции, он, вероятно, является хорошим кандидатом на роль собственного компонента.

Например, урезанная версия TodoListDaily может выглядеть так:

const TodoListDaily = ({ selectedDate, todoData }) => {
  return (
    <div className="todo-list-wrap">
      <h1 className="title-card">{selectedDate + `th May`}</h1>
      <ul className="list-group todo-list">
        {todoData
          .filter(item => item.date === selectedDate)
          .map(item => {
            return <ListItem key={item.id} {...item} />;
          })}
      </ul>
    </div>
  );
};

Это упрощает понимание, имея меньшие компоненты с меньшим количеством зависимостей. Но это также улучшает работу с React. Например, более детальные компоненты React избегают ненужного повторного рендеринга и помогают с инструментами разработки React, поскольку вы можете видеть реквизиты, переданные каждой записи списка.

Вы можете найти песочницу, которую я использовал для отладки здесь (включая извлеченный список компонент элемента): https://codesandbox.io/s/todo-app-k6i6l

...