I am using a fetch function to generate an output after pressing a button, this output is then used in several similar fetch functions. To do this I've used useEffect, but the issue is these 2nd and 3rd functions run before I press the button, the button click initiates the first fetch function and once this runs I would only then like the others to run. Otherwise it costs me a lot of money if they're on as soon as the page loads.
I know I should use useCallback, but simply replacing useEffect with useCallback doesn't work of course because it only runs when something is completed. I tried to replace the async function in the 2nd and 3rd functions with useCallBack, like so:
const getOpenAIResponse = async () => {
openai.createCompletion({
model: "text-davinci-003",
prompt: "Create a unique 1-5 word name.",
max_tokens: 256,
}).then((response) => {
setInputName(response.data.choices[0].text)
getSlogan()
})
};
const getStory = useCallback (() => {
openai.createCompletion({
model: "text-davinci-003",
prompt: "Create a story about " inputName ".",
max_tokens: 256,
}).then((response) => {
setInputStory(response.data.choices[0].text)
})
}, [inputName]);
However this did not work, the Story it produced was not based on the inputName - it assumed inputName was blank.
This is my code with useEffect.
const [inputName, setInputName] = useState('');
const [inputStory, setInputStory] = useState('');
const [inputDes, setInputDes] = useState('');
const getOpenAIResponse = async () => {
openai.createCompletion({
model: "text-davinci-003",
prompt: "Create a unique 1-5 word name.",
max_tokens: 256,
}).then((response) => {
setInputName(response.data.choices[0].text)
})
};
const getStory = async () => {
openai.createCompletion({
model: "text-davinci-003",
prompt: "Create a story about " inputName ".",
max_tokens: 256,
}).then((response) => {
setInputStory(response.data.choices[0].text)
})
};
const getDescription = async () => {
openai.createCompletion({
model: "text-davinci-003",
prompt: "Create a description for " inputName ".",
max_tokens: 256,
}).then((response) => {
setInputDes(response.data.choices[0].text)
})
};
useEffect(() => {
getStory();
getDescription();
}, [inputName]);
<Button onClick={getOpenAIResponse}>
Once I click the button everything settles down, but before I click it the inputStory and inputDescription are continously running in the background. I only want them to run once the button is clicked, but I need them to depend on the inputName state, so they need to wait for it to finish.
Is there a solution that doesn't run the 2nd and 3rd functions in the background?
CodePudding user response:
add a if condition to run the calls when input has values
useEffect(() => {
if(inputName){
getStory();
getDescription();
}
}, [inputName])