我正在开发一个待办事项应用程序,预期的流程是让用户输入他们的“待办事项”并单击“创建”,将待办事项添加到待办事项列表中,然后每个待办事项都会获得一个编辑按钮。该模式旨在在单击编辑按钮时出现,这将允许用户详细描述他们的待办事项。然而,目前当用户创建 Todo 时,模态框会弹出。
TODOLIST 组件
import TodoItem from "./TodoItem"
import { useState } from "react"
export default function TodoList( {todos, setTodos} ) {
const [editingItemId, setEditingItemId] = useState(null)
function editTask(id) {
setTodos(todos.map(todo => todo.id === id ? (
{...todo, isEditing: !todo.isEditing}
) : todo
));
setEditingItemId(id)
}
return (
<div className="grid grid-cols-4 gap-4">
{todos.map((todo, index) => (
<TodoItem
key={index}
task={todo}
editTask={editTask}
editingItemId={editingItemId}
/>
))}
</div>
)
}
TODOITEM 组件
import { useEffect } from "react";
export default function TodoItem({ task, editTask, editingItemId }) {
useEffect(() => {
if (task.isEditing && task.id === editingItemId) {
displayDialog();
}
}, [task.isEditing, task.id, editingItemId]);
function displayDialog() {
document.querySelector('dialog').showModal();
}
return (
<>
<div className="col-span-4">
<h2>{task.task}</h2>
{task.description ? <p>{task.description}</p> : (
<button
onClick={() => editTask(task.id)}
className="bg-slate-600 hover:bg-slate-900 text-white font-bold px-2 py-1 m-1 rounded-2xl">
Describe your task
</button>
)}
</div>
<dialog className="flex flex-col p-12 rounded-lg bg-slate-900 text-white">
<h2 className="uppercase">{task.task}</h2>
<textarea cols="60" rows="14" className="bg-slate-900 border border-white" />
</dialog>
</>
);
}
您正在尝试将普通的 javascript DOM 操作与 React 混合在一起。您可能想要选择其中一个,否则 React 的内部 React 组件树将与 DOM 不同步,并且您将遇到一百万个错误。要以 React 方式执行此操作,您通常会有条件地渲染对话框,而不是尝试使用 CSS 显示/隐藏它。类似...
return (
<>
<div className="col-span-4">
<h2>{task.task}</h2>
{task.description ? <p>{task.description}</p> : (
<button
onClick={() => editTask(task.id)}
className="bg-slate-600 hover:bg-slate-900 text-white font-bold px-2 py-1 m-1 rounded-2xl">
Describe your task
</button>
)}
</div>
{ selectedID === task.id &&
<dialog className="flex flex-col p-12 rounded-lg bg-slate-900 text-white">
<h2 className="uppercase">{task.task}</h2>
<textarea cols="60" rows="14" className="bg-slate-900 border border-white" />
</dialog>
}
</>
);