我正在對 API 進行異步呼叫,然后在 useEffect 函式中將回傳的資料設定回狀態變數。然后在該函式之外,我將值分解為變數并將它們呈現到螢屏上。
問題是指令變數在渲染時仍然未定義,我有點困惑為什么其他人渲染得很好。
(指令變數也是一個物件陣列)
頂部組件
const RecipePage = () => {
const [isLoading, setIsLoading] = useState(true);
const [data, setData] = useState([]);
const params = useParams();
const recipeSlug = params.recipeSlug;
const recipeID = params.id;
useEffect(() => {
const options = {
method: 'GET',
url: 'https://tasty.p.rapidapi.com/recipes/detail',
params: { id: recipeID },
headers: {
'x-rapidapi-host': 'tasty.p.rapidapi.com',
'x-rapidapi-key': process.env.REACT_APP_RAPID_API_KEY
}
};
const fetchData = async () => {
const recipeInstructions = await axios.request(options);
setData(recipeInstructions.data);
console.log(recipeInstructions.data);
console.log(data);
}
fetchData().catch(console.error);
}, [recipeID]);
const { name, country, slug, instructions, beauty_url } = data;
console.log(data.instructions);
console.log(name);
return (
<>
<header className="topBar">
<Link to={`/`} className='normal'>
<div className='title'>
<SectionTitle titleText="Test Test" />
<SectionTitle titleText="Cooking Club" />
</div>
</Link>
</header>
<div>
<SectionTitle titleText={name} />
<div className="image">
<img src={beauty_url} alt="recipe" />
</div>
</div>
<section>
<p>Serves {data.num_servings} </p>
<p>Prep Time {data.num_servings} </p>
</section>
<section>
<h3>Ingredients</h3>
</section>
<div>{country}</div>
<div>{slug}</div>
<div>slug: {recipeSlug}</div>
<RecipeInstructions instructions={instructions} />
</>
)
}
說明組件
const RecipeInstructions = ({instructions}) => {
console.log(instructions);
const instructionList = instructions.map((instruction, i) =>{
return <li key={instruction.id} id ={instruction.id}>{instruction.display_text}</li>
});
return(
<ul className="instructionList">
{instructionList}
</ul>
)
}
匯出默認配方指令;
JSON 形狀
{
"country": "US",
"name": "Tomato And Ginger Pressure Cooker Short Ribs",
"id": 8115,
"original_video_url": "https://s3.amazonaws.com/video-api-prod/assets/394e5b5d88d44a8abff0bf146ccda0b8/Campbells_TomatoGingerRibs_BFV88856_SQHero.mp4",
"cook_time_minutes": null,
"description": "",
"slug": "tomato-and-ginger-pressure-cooker-short-ribs",
"instructions": [
{
"appliance": null,
"id": 70698,
"display_text": "Season the short ribs all over with salt and pepper.",
"position": 1,
"start_time": 4166,
"end_time": 14133,
"temperature": null
},
{
"display_text": "Turn the pressure cooker on to the Sauté setting. Add the olive oil to the pot and heat until shimmering. Working in batches, add the short ribs and sear on all sides until browned, 2–3 minutes per side. Once all of the short ribs have been seared, return to the pot, nestling to fit in an even layer.",
"position": 2,
"start_time": 0,
"end_time": 0,
"temperature": null,
"appliance": null,
"id": 70699
},
{
"start_time": 16500,
"end_time": 30333,
"temperature": null,
"appliance": null,
"id": 70700,
"display_text": "In a small bowl, whisk together the soy sauce, beef broth, sesame oil, red pepper flakes, brown sugar, garlic, and ginger.",
"position": 3
},
{
"end_time": 61500,
"temperature": null,
"appliance": null,
"id": 70701,
"display_text": "Pour the sauce and Campbell’s? Tomato Soup into the pot over the short ribs. Secure the lid and turn off the Sauté setting, then set to pressure cook on high for 1 hour.",
"position": 4,
"start_time": 50500
},
{
"end_time": 0,
"temperature": null,
"appliance": null,
"id": 70702,
"display_text": "In a small bowl, whisk together the cornstarch, water, and mirin until smooth.",
"position": 5,
"start_time": 0
},
{
"end_time": 47000,
"temperature": null,
"appliance": null,
"id": 70703,
"display_text": "Release the pressure valve until all the steam has been released. Transfer the short ribs to a bowl and skim off any fat from the surface of the braising liquid. Turn on the Sauté setting and stir the cornstarch slurry into the braising liquid. Bring to a simmer and cook until the sauce has thickened, about 3 minutes. Return the short ribs to the pressure cooker and turn to coat in the sauce.",
"position": 6,
"start_time": 35000
},
{
"position": 7,
"start_time": 93000,
"end_time": 98333,
"temperature": null,
"appliance": null,
"id": 70704,
"display_text": "Serve the short ribs over white rice and garnish with sliced scallions and sesame seeds."
},
{
"position": 8,
"start_time": 100000,
"end_time": 103000,
"temperature": null,
"appliance": null,
"id": 70705,
"display_text": "Enjoy!"
}
],
"beauty_url": "https://img.buzzfeed.com/video-api-prod/assets/dc16dd0e35f2480ba1d68badac0eec99/InstantPotShortRibs_Pinterest.jpg",
"num_servings": 4,
"facebook_posts": []
}
uj5u.com熱心網友回復:
useEffect 鉤子在第一次初始渲染之后首先執行,而且請求是異步的,這意味著在接收到網路回應之前至少會有一個渲染,并且資料物件將填充指令值。
這是預期的行為,您可以選擇延遲渲染組件的一部分,直到獲取資料,或者提供一些加載狀態。
uj5u.com熱心網友回復:
您已經被重定向到專用頁面,因此您有或沒有 recipeId 無需在 useEffect 中使用依賴項陣列您可以使用條件渲染,因為您的呼叫是 asynchrone ,您可以在完成后顯示一個 gif 加載示例顯示資訊。
const RecipePage = () => {
const [isLoading, setIsLoading] = useState(false);
const [data, setData] = useState([]);
const params = useParams();
const recipeSlug = params.recipeSlug;
const recipeID = params.id;
useEffect(() => {
setIsLoading(true)
const options = {
method: 'GET',
url: 'https://tasty.p.rapidapi.com/recipes/detail',
params: { id: recipeID },
headers: {
'x-rapidapi-host': 'tasty.p.rapidapi.com',
'x-rapidapi-key': process.env.REACT_APP_RAPID_API_KEY
}
};
const fetchData = async () => {
const recipeInstructions = await axios.request(options);
setData(recipeInstructions.data);
console.log(recipeInstructions.data);
console.log(data);
}
fetchData().catch(console.error);
setIsLoading(false)
}, []);
const { name, country, slug, instructions, beauty_url } = data;
console.log(data.instructions);
console.log(name);
if(isLoading) {
return (
<div> here dispolay a gif loading </div>
)};
return (
<>
<header className="topBar">
<Link to={`/`} className='normal'>
<div className='title'>
<SectionTitle titleText="Test Test" />
<SectionTitle titleText="Cooking Club" />
</div>
</Link>
</header>
<div>
<SectionTitle titleText={name} />
<div className="image">
<img src={beauty_url} alt="recipe" />
</div>
</div>
<section>
<p>Serves {data.num_servings} </p>
<p>Prep Time {data.num_servings} </p>
</section>
<section>
<h3>Ingredients</h3>
</section>
<div>{country}</div>
<div>{slug}</div>
<div>slug: {recipeSlug}</div>
<RecipeInstructions instructions={instructions} />
</>
)
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/434342.html
標籤:javascript 数组 反应 json 不明确的
下一篇:打字稿中的嵌套過濾器
