Reputation: 135
Basically, as you can see in the code, I only want to run one of these API requests. If origCompId is passed, it runs duplicateInstance
, otherwise, it runs addNewInstance
. origCompId is a query parameter so it takes a second for it to update. This causes addNewInstance
to run because origCompId begins as 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. The problem is, that I need this hook to run when the app first loads. I can’t separate these API calls. If the user is loading the app for the first time, it’ll run addNewInstance
and load their initial data. If the user duplicates their existing app, it’ll have origCompId and run 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;
Upvotes: 0
Views: 93
Reputation: 1
You want to run your side effect exactly when your component gets information about origCompId whether it exists or not. 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.
Upvotes: 0
Reputation: 413
I think you can set the initial props to null / undefined so that non of the statement will run before your api completes
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
Possible to have better solutions and I am open for that
Upvotes: 2