[英]I’m having trouble figuring out the logic in my custom hook
Basically, as you can see in the code, I only want to run one of these API requests.基本上,正如您在代码中看到的,我只想运行这些 API 请求之一。 If origCompId is passed, it runs duplicateInstance
, otherwise, it runs addNewInstance
.如果 origCompId 被传递,它运行duplicateInstance
,否则,它运行addNewInstance
。 origCompId is a query parameter so it takes a second for it to update. origCompId 是一个查询参数,因此它需要一秒钟才能更新。 This causes addNewInstance
to run because origCompId begins as null.这会导致addNewInstance
运行,因为 origCompId 以 null 开头。 I feel like the logic is simple here, but for some reason, I'm just not seeing the solution.我觉得这里的逻辑很简单,但由于某种原因,我只是没有看到解决方案。
I tried adding the hasRendered
ref, as you can see, but that didn't prevent it from happening.如您所见,我尝试添加hasRendered
ref,但这并没有阻止它发生。 The problem is, that I need this hook to run when the app first loads.问题是,我需要这个钩子在应用程序第一次加载时运行。 I can't separate these API calls.我无法分离这些 API 调用。 If the user is loading the app for the first time, it'll run addNewInstance
and load their initial data.如果用户是第一次加载应用程序,它将运行addNewInstance
并加载他们的初始数据。 If the user duplicates their existing app, it'll have origCompId and run duplicateInstance
.如果用户复制他们现有的应用程序,它将具有 origCompId 并运行duplicateInstance
。
Any help would be much appreciated!任何帮助将非常感激!
import { useEffect, useRef } from "react";
import { addNewInstance, duplicateInstance } from "../util/services";
const useAddInstanceToDB = (instance, compId, origCompId) => {
const hasRendered = useRef<boolean | null>(null);
useEffect(() => {
const controller = new AbortController();
if (hasRendered.current) {
if (instance && compId && origCompId) {
duplicateInstance(instance, controller, compId, origCompId);
} else if (instance && compId) {
addNewInstance(instance, controller, compId);
}
}
return () => {
controller.abort();
hasRendered.current = true;
};
}, [instance, compId, origCompId]);
};
export default useAddInstanceToDB;
I think you can set the initial props to null / undefined so that non of the statement will run before your api completes我认为您可以将初始道具设置为 null / undefined 以便在您的 api 完成之前运行非语句
useAddInstanceToDB(undefined, undefined, undefined);
const useAddInstanceToDB = (instance, compId, origCompId) => {
useEffect(() => {
const controller = new AbortController();
if (origCompId) {
if (instance && compId && origCompId !== -1) { // will not run when hook is inited
duplicateInstance(instance, controller, compId, origCompId);
} else if (instance && compId && origCompId === -1) { // also will not run when hook is inited, only run when instance and compId is defined
addNewInstance(instance, controller, compId);
}
}
return () => {
controller.abort();
};
}, [instance, compId, origCompId]);
};
setOrigCompId to -1 if new instance is needed, or any value other than -1 if duplicate is needed如果需要新实例,则 setOrigCompId 为 -1,如果需要重复,则为 -1 以外的任何值
Possible to have better solutions and I am open for that可能有更好的解决方案,我对此持开放态度
You want to run your side effect exactly when your component gets information about origCompId whether it exists or not.您希望在您的组件获取有关origCompId的信息时准确地运行您的副作用,无论它是否存在。 Right now your component just can't know when the data is loaded - so you can't do anything.现在,您的组件无法知道数据何时加载——因此您无能为力。 So you need to tell it to your component - you can set origCompId = -1 if it not exists (as suggested by previous author), but I advise you to create a new variable that will tell your component that all the data has loaded.所以你需要告诉你的组件 - 如果它不存在,你可以设置origCompId = -1 (如前作者所建议的那样),但我建议你创建一个新变量,告诉你的组件所有数据都已加载。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.