【发布时间】:2021-09-14 23:53:57
【问题描述】:
我是新来的,正在处理一个从外部 api 获取配方详细信息的小项目。 一旦页面加载,我就能够呈现食谱列表,但我面临的挑战是,一旦状态中的值发生变化,我正在尝试进行条件渲染以呈现食谱详细信息。即:如果 PageIndex === 1 则加载配方列表,如果 PageIndex === 0 则加载配方详细信息。
配方列表加载没有任何问题,我可以转到配方详细信息页面,但是一旦我单击转到配方详细信息,配方列表组件就会卸载。当我单击一个按钮返回到配方列表时,我得到一个错误 TypeError: Cannot read property 'map' of undefined.
当我在按钮单击时将索引值更改回 1 时,如何让组件重新呈现。
下面是我的代码
注意:我将 props handleIndex 传递给 RecipeDetails,这是我在用户单击返回食谱列表时运行的代码。
应用js
import React, { Fragment, useState, useEffect } from 'react';
import { recipes } from './tempList';
import RecipeList from './components/RecipeList';
import RecipeDetails from './components/RecipeDetails';
import './App.css';
import '../node_modules/bootstrap/dist/css/bootstrap.min.css';
import Header from './components/Header';
const App = () => {
const [data, setData] = useState({
recipes: [],
url: 'https://forkify-api.herokuapp.com/api/search?q=pizza',
details_id: 47746,
pageIndex: 1,
});
const { url, recipes, details_id, pageIndex } = data;
const getRecipes = () => {
fetch(url)
.then((res) => res.json())
.then((jsonData) => {
setData({ ...data, recipes: jsonData.recipes });
})
.catch((err) => {
console.log(err);
});
};
useEffect(() => {
getRecipes();
}, []);
const handleIndex = (index) => {
setData({ pageIndex: index });
};
const handleDetails = (index, id) => {
setData({
pageIndex: index,
details_id: id,
});
};
return (
<Fragment>
<Header />
{pageIndex === 1 ? (
<RecipeList recipes={recipes} handleDetails={handleDetails} />
) : (
<RecipeDetails details_id={details_id} handleIndex={handleIndex} />
)}
</Fragment>
);
};
配方详情
import React, { Fragment, useState, useEffect } from 'react';
import { Link, BrowserRouter } from 'react-router-dom';
const RecipeDetails = ({ handleIndex, details_id }) => {
const [recipeDetails, setRecipeDetails] = useState({
recipe: [],
});
const { recipe } = recipeDetails;
const id = details_id;
const url = `https://forkify-api.herokuapp.com/api/get?rId=${id}`;
const getRecipe = () => {
fetch(url)
.then((res) => res.json())
.then((data) => {
setRecipeDetails({
recipe: data.recipe,
});
})
.catch((err) => {
console.log(err);
});
};
useEffect(() => {
getRecipe();
}, []);
console.log(recipe);
const {
image_url,
title,
source_url,
publisher,
publisher_url,
ingredients,
} = recipe;
return (
<Fragment>
<div className='container'>
<div className='row'>
<div className='col-10 mx-auto col-md-6 my-3'>
<BrowserRouter>
<Link to='/'>
<button
type='button'
className='btn btn-warning mb-5 text-capitalize'
onClick={() => handleIndex(1)}
>
back to recipe list
</button>
</Link>
</BrowserRouter>
<img src={image_url} alt='recipe' className='d-block w-100' />
</div>
<div className='col-10 mx-auto col-md-6 my-3'>
<h6 className='text-uppercase'>{title}</h6>
<h6 className='text-warning text-capitalize'>
Publisher: {publisher}
</h6>
<a
href={publisher_url}
target='_blank'
rel='noopener noreferrer'
className='btn btn-primary mt-2 text-capitalize'
>
publisher page
</a>
<a
href={source_url}
target='_blank'
rel='noopener noreferrer'
className='btn btn-success mx-3 mt-2 text-capitalize'
>
recipe url
</a>
<ul className='list-group mt-4'>
<h2 className='mt-3 mb-4'>Ingredients</h2>
{ingredients === undefined ? (
<p>Loading...</p>
) : (
ingredients.map((item, index) => {
return (
<li key={index} className='list-group-item text-slanted'>
{item}
</li>
);
})
)}
</ul>
</div>
</div>
</div>
</Fragment>
);
};
export default RecipeDetails;
【问题讨论】:
标签: javascript reactjs react-hooks