我正在使用React和TypeScript构建一个To Do列表项目。在重构代码并将不同的div(Active tasks,Done tasks,All tasks)分解到组件文件夹中的单独文件中的过程中,我的项目不再能够过滤掉“完成”或“活动”的任务(这是由ToDoItem文件中的复选框值确定的,它已被压缩为一个prop:onUpdateToDo)我很困惑,不知道在我的“Done”文件中从哪里过滤掉我的ToDoItem,因为我认为它应该在visibleTodos函数中Map出来。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>
);
}
Done.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传递了错误的props?在我重构代码之前,我的ShowDone()函数工作正常,由于某种原因,showDone函数中的条件没有被调用,我得到了一个重复的App.tsx文件,而它应该返回我的ToDoItems。
1条答案
按热度按时间xzlaal3s1#
这与这条线有关,我相信:
由于
x
和toDoItem
都是对象,===
检查引用相等性,因此这将始终为false。它们可能看起来像同一个对象,但它们引用内存中的不同对象,因此不相等。您需要一些其他方法来检查它们是否是相同的ToDo项,例如数组中的索引或某个id
字段,这样您就可以正确地判断要更新哪些待办事项。