我在 page.tsx 文件中使用以下挂钩,然后将数据传递到表中。当我点击一个任务时,我有以下功能
page.tsx “使用客户端”
const { allOpenTasks, getOpenTasks } = useTasks();
useEffect(() => {
const fetchTasks = async () => {
await getOpenTasks(user.id);
};
fetchTasks();
}, []);
useTasks.tsx
export const useTasks = () => {
const [allOpenTasks, setAllOpenTasks] = useState<any>([]);
const getOpenTasks = async (userId: any) => {
try {
const { data, error } = await supabase
.from("task")
.select(
`
id,
is_complete
`
)
.eq("owner_id", userId);
if (error) {
throw error;
}
if (data) {
setAllOpenTasks(data);
}
} catch (error: any) {
console.log(error.message);
}
};
const setTaskCompleted = function (taskId: any) {
const updatedTasks = allOpenTasks.map((task: any) =>
task.id === taskId ? { ...task, is_complete: !task.is_complete } : task
);
setAllOpenTasks([...updatedTasks]);
};
return {
allOpenTasks,
getOpenTasks,
setTaskCompleted
};
};
表.tsx “使用客户端”
const { setTaskCompleted } = useTasks();
const clickCompleteTask = async (taskId: any) => {
try {
const { error } = await supabase
.from("task")
.update({
is_complete: true,
})
.eq("id", taskId);
if (error) throw new Error();
setTaskCompleted(taskId);
} catch (err) {
console.log(err);
}
};
我已经尝试过以下有效的方法。 我可以将其维护在 page.tsx 文件中,并且只使用钩子从 supabase 获取数据,而不是将任务状态保留在钩子内。
我认为如果它位于钩子内部,它看起来会更干净,但它不会在任务对象的状态更改时重新渲染(当其设置为完成时)
我怀疑它是因为当 setTaskCompleted 在开始时初始化时, allOpenTasks 是空的,因为 supabase 还没有设置它。
如果有更好的模式,我也愿意接受。
谢谢!
你可以尝试一下吗
const setTaskCompleted = function (taskId: any) {
if (allOpenTasks.length > 0) {
const updatedTasks = [...allOpenTasks].map((task: any) =>
task.id === taskId ? { ...task, is_complete: !task.complete } : task
);
setAllOpenTasks(updatedTasks);
} else {
console.log("Tasks not loaded yet, cannot update completion status.");
}
};
解决这个问题并确保当 allOpenTasks 中的数据发生变化时重新渲染。
我认为它有两个问题,
if (allOpenTasks.length > 0)
如果supabase返回空,则数据为空,确保在更新之前获取数据我有条件。[...allOpenTasks].map
为了解决这个问题并确保当 allOpenTasks
内的数据发生变化时重新渲染。无论如何,我认为你的代码总体来说是完美的