如何让fetchMovieDescription函数在story状态更新后再执行?
问题解决:确保fetchMovieDescription在story更新后执行
问题根源
setStory是异步操作,原代码中调用setStoryFetched(true)时,story还未完成更新,导致fetchMovieDescription拿到的是旧值或空值,生成不匹配的图片。storyFetched设为true后未重置,后续提交时状态无变化,useEffect不会再次触发,无法生成新图片。
解决方案
移除storyFetched状态,直接监听story的变化;每次提交前重置图片状态,避免旧内容残留。
修改后的完整代码
import { process } from '../env' import { Configuration, OpenAIApi } from 'openai' import { useState, useEffect } from 'react' const configuration = new Configuration({ apiKey: process.env.OPENAI_API_KEY }) const openai = new OpenAIApi(configuration) export default function StoryPart() { const [userInput, setUserInput] = useState("") const [story, setStory] = useState("") const [images, setImages] = useState("") // 监听story变化,仅当story有值时调用图片生成函数 useEffect(() => { if (story) { fetchMovieDescription(story); } }, [story]) const handleChange = (event) => { setUserInput(event.target.value); } const handleSubmit = async (event) => { event.preventDefault(); // 提交前清空旧图片,保证加载状态正确显示 setImages(""); await fetchBotReply(userInput); setUserInput(""); } async function fetchBotReply(userInput) { try { const response = await openai.createCompletion({ model: 'text-davinci-003', prompt: `You are an AI developed by OpenAI. You have been trained on a vast range of internet text. But unlike most AI models, your specialty is in creating unique and compelling movie scenarios. You understand the elements of a great movie, including plot development, character arcs, conflict, and resolution. You can generate scenarios in any genre, time period, or setting. Your task is to write a scenario based on: ${userInput}.You must create the scenario so its easy to split it into 5 sections.The reason for it is that based on each section i will later ask you to write 5 detailed descriptions of an image for later image generation.`, max_tokens: 700, temperature: 1 }) setStory(response.data.choices[0].text) } catch (error) { console.log(error) } } async function fetchMovieDescription(story) { try { const response = await openai.createImage({ prompt: `Create a descriptive and precise prompt for image generation based on this story: ${story}`, n: 1, size: "512x512", response_format: 'url' }) setImages(response.data.data[0].url) } catch (error) { console.log(error) } } return ( <div className="StoryPart"> <form onSubmit={handleSubmit}> <label> Story: <input value={userInput} type="text" name="story" placeholder='input prompt' onChange={handleChange}/> </label> <button type="submit" value="Submit">Submit</button> </form> {story? <p>{story}</p> : "Writing your story..."} {images? <img src={images} alt="movie scene"/> : "Generating your image..."} </div> ) }
关键修改点
- 移除
storyFetched相关状态与逻辑,改用useEffect直接监听story变量,确保story更新后才触发图片生成。 - 在
useEffect中增加if (story)判断,避免初始空值时调用fetchMovieDescription。 - 在
handleSubmit中新增setImages(""),每次提交时清空旧图片,保证加载状态提示准确。
内容的提问来源于stack exchange,提问作者Luka Minđek
相关产品推荐
相关产品推荐

