React Typescript:重构代码后无法过滤数组

问题描述 投票:0回答:0

我正在使用 React 和 TypeScript 构建一个待办事项列表项目。在重构我的代码并将不同的 div(活动任务、完成任务、所有任务)分解为组件文件夹中的单独文件的过程中,我的项目不再能够过滤掉“完成”或“活动”的任务(这是由我的 ToDoItem 文件中的复选框值决定的,它已被压缩为一个道具:onUpdateToDo)我很困惑并坚持在我的“完成”文件中过滤掉我的 ToDoItem 的位置,因为我认为它应该被映射在 visibleTodos 函数中输出。 visibleToDos 函数在我的 App.tsx 文件中。

App.tsx

  const initialTodosString = localStorage.getItem("toDoList");
  
  const initialTodos = initialTodosString
  ? JSON.parse(initialTodosString)
  : [myToDo1, myToDo2];


  export function App(): JSX.Element {
  const [toDos, setToDos] = useState<ToDo[]>(initialTodos);
  const [addingToDo, setAddingToDo] = useState(false);
  const [showingDoneTasks, setShowDoneTasks] = useState(false); // show true if not
  const [showingActiveTasks, setShowActiveTasks] = useState(false); // show true if not
  const [showingAllTasks, setShowAllTasks] = useState(false);
  const [filterTodosCompleted, setFilterTodosCompleted] = useState<any | null>(
    null
  );

// VISIBLE TO DOS FUNCTION BELOW //

  const visibleTodos = useMemo(
    () =>
      toDos.filter((toDo) => {
        if (filterTodosCompleted === null) {
          return true;
        }
        return filterTodosCompleted === toDo.checked;
      }),
    [filterTodosCompleted, toDos]
  );

  useEffect(
    function () {
      localStorage.setItem("toDoList", JSON.stringify(toDos));
    },
    [toDos]
  );

// Showing Active Tasks function //

  function showAllTasks(){
    setShowAllTasks(true)
    setShowDoneTasks(false);
    setShowActiveTasks(false);
  }

  if (showingAllTasks) return (
    <AllTasks newTask={newTask}
    showActive={showActive}
    toDos={toDos}
    showDone={showDone}
    visibleTodos={toDos}
    setToDos={setToDos}/>
  )

  function showActive() {
    setShowActiveTasks(true);
    setFilterTodosCompleted(false);
    setShowDoneTasks(false);
  }

  function newTask() {
    setAddingToDo(true);
  }

  if (showingActiveTasks) {
    return (
      <ActiveTasks
        newTask={newTask}
        showActive={showActive}
        toDos={toDos}
        showDone={showDone}
        visibleTodos={toDos}
      />
    );
  }

/// showing Done Tasks function and jsx component with props being passed within

  function showDone() {
    setShowDoneTasks(true);
    setFilterTodosCompleted(true);
    setShowActiveTasks(false);
  }

  if (showingDoneTasks) {
    return (
      <DoneTasks
        newTask={newTask}
        showActive={showActive}
        toDos={toDos}
        showDone={showDone}
        visibleTodos={toDos}
        setToDos={setToDos}
        showAllTasks={showAllTasks}
      />
    );
  }
 if (addingToDo) {
    return (
      <NewTask
        newTask={newTask}
        showActive={showActive}
        toDos={toDos}
        showDone={showDone}
        visibleTodos={toDos}
        handleFormSubmit={handleFormSubmit}
      />
    );
  }

  function handleFormSubmit(event: FormEvent<HTMLFormElement>) {
    const data = Object.fromEntries(
      new FormData(event.target as HTMLFormElement)
    );
    const newDueDate = new Date(data.Date as string);
    const timeZoneCorrectedDate = new Date(
      newDueDate.getTime() + newDueDate.getTimezoneOffset() * 60 * 1000
    ); //
    debugger;
    setToDos([
      ...toDos,
      {
        title: data.Title as string,
        priority: parseInt(data.Priority as string) as 2 | 1,
        description: data.Description as string,
        checked: false,
        duedate: data.Date ? timeZoneCorrectedDate.getTime() : undefined,
      },
    ]);
  }

  return (
    <div className="App">
      <div className="greeting-container">
        <div className="greeting">
          <Greeting />
        </div>
        <button className="task-button" onClick={newTask}>
          New Task
        </button>
        <div className="date-container">
          Today is {new Date().toLocaleString("en-US", { weekday: "long" })}
          <br />
          <div className="current-date">
            {new Date().toLocaleString("en-US", {
              month: "long",
              day: "2-digit",
            })}
            , {new Date().getFullYear()}
          </div>
        </div>
      </div>
      <div className="task-container">
        <div className="task-counter">
          {toDos.length} {toDos.length === 1 ? "Task" : "Tasks"}
        </div>
        <div className="status-container">
          <button id="allButton" onClick={showAllTasks}>
            All
          </button>
          <button id="activeButton" onClick={showActive}>
            Active
          </button>
          <button id="doneButton" onClick={showDone}>
            Done
          </button>
        </div>
      </div>
      <hr />
      {showingDoneTasks ? (
        <DoneTasks
          newTask={newTask}
          showActive={showActive}
          toDos={toDos}
          showDone={showDone}
          visibleTodos={toDos}
          setToDos={setToDos}
          showAllTasks={showAllTasks}/>) : null}



      {visibleTodos.map((toDoItem: ToDo) => (
        <ToDoItem
          onDeleteToDo={function () {
            const updatedToDos = toDos.filter((x) => x !== toDoItem);
            setToDos(updatedToDos);
          }}
 onUpdateTodo={function (updates: any) {
            const updatedToDos = toDos.map((x) =>
              x === toDoItem ? ({ ...x, ...updates } as any) : x
            );
            console.log(updates);
            setToDos(updatedToDos);
          }}
          toDo={toDoItem}
        />
      ))}
    </div>
  );
}


完成.tsx

import { ToDo } from "../types/ToDo";
import { Greeting } from "./Greeting";
import { ToDoItem } from "./ToDoItem";

export const DoneTasks = (props:{
  newTask: () => void
  showActive: () => void
  toDos: ToDo[];
  showDone: () => void
  visibleTodos: ToDo[];
  setToDos: (value: React.SetStateAction<ToDo[]>) => void
  showAllTasks: () => void


}) => (
  <div className="App">
    <div className="greeting-container">
      <div className="greeting">
        <Greeting />
      </div>
      <button className="task-button" onClick={props.newTask}>
        New Task
      </button>
      <div className="date-container">
        Today is {new Date().toLocaleString("en-US", { weekday: "long" })}
        <br />
        <div className="current-date">
          {new Date().toLocaleString("en-US", {
            month: "long",
            day: "2-digit",
          })}
          , {new Date().getFullYear()}
        </div>
      </div>
    </div>
    <div className="task-container">
      <div id="completed-task-counter">
        {props.toDos.length}{" "}
        {props.toDos.length === 1 ? "Completed Task" : "Completed Tasks"}
      </div>
      <div className="status-container">
      <button id="allButton" onClick={props.showAllTasks}>
            All
          </button>
        <button className="activeButton" onClick={props.showActive}>
          Active
        </button>
        <button className="doneButton" onClick={props.showDone}>
          Done
        </button>
      </div>
    </div>
    <hr />


    {props.visibleTodos.map((toDoItem: ToDo) => (
        <ToDoItem
          onDeleteToDo={function () {
            const updatedToDos = props.toDos.filter((x) => x !== toDoItem);
            props.setToDos(updatedToDos);

          }}
         
          onUpdateTodo={function (updates: any) {
            const updatedToDos = props.toDos.map((x) =>
              x === toDoItem ? ({ ...x, ...updates } as any) : x
            );
            console.log(updates);
            props.setToDos(updatedToDos);
          }}
          
          toDo={toDoItem}
        />
      ))}
    </div>
  );
 

ToDoItem.tsx

export function ToDoItem(props: {
  toDo: ToDo;
  onDeleteToDo: any;
  onUpdateTodo: any;
}) {
  const handleOptionsChange = (event: any) => {
    const selectBox = event.target;
    const newValue = selectBox.value;
    const newPriority = parseInt(newValue);
  
    props.onUpdateTodo({ priority: newPriority })
  };
  const checkBoxCheck = (event: any) => {
    const checkBox = event.currentTarget.checked;
    const newCheckBoxValue = checkBox;

    props.onUpdateTodo({ checked: newCheckBoxValue })
    console.log(newCheckBoxValue)
  };
  const handleDateChange =(event: any) => {
    const newDate = event.target.value;

    props.onUpdateTodo({ duedate: newDate })

    console.log(newDate)
  }

  if (!props.toDo) {
    return <p>Missing To Do</p>;
  }

  return (
    <div
      className="to-do-item"
      data-priority={props.toDo.priority}
      id="to-do-item"
    >
      <div className="checkbox-title-container">
        <div className="check-title-div">
          <div>
            <input
              type="checkbox"
              id="checkbox"
              onChange={checkBoxCheck}
              checked={props.toDo.checked}
            />
          </div>

          <h2 className="to-do-title">{props.toDo.title}</h2>
        </div>
        <div id="delete-div">
          <select
            name="Priority"
            className="select-field"
            value={props.toDo.priority}
            onChange={handleOptionsChange}
          >
            <option value="1">Important</option>
            <option value="2">Normal</option>
          </select>
          <button id="delete" onClick={props.onDeleteToDo}>
            Delete
          </button>
        </div>
        <span className="to-do-date-container">
        <input name="Date" type="date" className="to-do-date-input" value={props.toDo.duedate
            ? new Date(props.toDo.duedate).toISOString().split('T')[0]
            : undefined} onChange={handleDateChange}/>
         
        </span>
        <div className="description-box">
          <span className="description">{props.toDo.description}</span>
        </div>
      </div>
      <br />
    </div>
  );
}

我不确定我是否将错误的道具传递给 DoneTasks?在我重构我的代码之前,我的 ShowDone() 函数工作正常,由于某种原因,showDone 函数中的条件没有被调用,我得到了我的 App.tsx 文件的副本,而它应该返回我检查过的 ToDoItems。

javascript reactjs typescript refactoring react-props
© www.soinside.com 2019 - 2024. All rights reserved.