我在做一个食谱应用。我希望useres能够添加食谱的最爱列表。React有3个组件。配方、添加到收藏夹和收藏夹。
配方组件显示有关所选配方的各种详细信息。
AddToFavorites组件是在Recipe组件中呈现的按钮。
“收藏夹”组件是一个列表,显示使用“添加到收藏夹”按钮添加到收藏夹的所有项目。
function Favorites() {
const [favList, setFavList] = useState(localStorage.getItem('favorites'));
return (
<FavPageContainer>
{favList}
{favList.map(listItem => {
<li>{listItem}</li>
})}
</FavPageContainer>
)
}
function Recipe() {
let params = useParams();
const [details, setDetails] = useState({});
const [activeTab, setActiveTab] = useState('summary');
const fetchDetails = async () => {
const data = await fetch(`https://api.spoonacular.com/recipes/${params.name}/information?apiKey=${process.env.REACT_APP_API_KEY}`);
const detailData = await data.json();
setDetails(detailData);
}
useEffect(() => {
fetchDetails();
}, [params.name]);
return (
<DetailWrapper>
<h2>{details.title}</h2>
<img src={details.image} alt="" />
<Info>
<ButtonContainer>
<AddToFavorites details={details}/>
<Button
className={activeTab === 'summary' ? 'active' : ''}
onClick={() => setActiveTab('summary')}>Nutrition Info
</Button>
<Button
className={activeTab === 'ingredients' ? 'active' : ''}
onClick={() => setActiveTab('ingredients')}>Ingredients
</Button>
<Button
className={activeTab === 'instructions' ? 'active' : ''}
onClick={() => setActiveTab('instructions')}>Instructions
</Button>
</ButtonContainer>
{activeTab === 'instructions' && (
<div>
<p dangerouslySetInnerHTML={{__html: details.instructions}}></p>
</div>
)}
{activeTab === 'ingredients' && (
<ul>
{details.extendedIngredients &&
details.extendedIngredients.map((ingredient) => (
<li key={ingredient.id}> {ingredient.original}</li>
))}
</ul>
)}
{activeTab === 'summary' && (
<div>
<p dangerouslySetInnerHTML={{__html: details.summary}}></p>
</div>
)}
</Info>
</DetailWrapper>
)
}
function AddToFavorites(details) {
const [active, setActive] = useState(false);
const [favorites, setFavorites] = useState([]);
const handleActive = () => {
setActive(!active);
};
const handleFavorites = () => {
handleActive();
if(active){
removeFromFavorites();
} else if(!active) {
addToFavorites();
}
};
const addToFavorites = () => {
handleActive();
setFavorites([...favorites, details]);
console.log(favorites)
localStorage.setItem('favorites', JSON.stringify(favorites));
};
return (
<AddToFavBtn className={active ? 'active' : null} onClick={handleFavorites}>
{!active ? 'Add to favorites' : 'Remove from favorites'}
<div>
<BsFillSuitHeartFill/>
</div>
</AddToFavBtn>
)
}
到目前为止,我一直在努力做的是:
- 将API数据作为Recipe中的'details' props传递给AddToFavorites。
- 在AddToFavorites中将收藏夹设置为默认为空数组的状态。
- 在AddToFavorites中添加onClick事件以添加到收藏夹btn,该事件调用AddToFavorites()函数。
- 在AddToFavorites()函数中,我尝试通过使用spread操作符并将接收到的详细信息props(其中包含API数据)作为新项添加到状态数组的新副本中,然后将其存储在本地存储中,从而不可变地更新收藏夹状态。
将项目添加到收藏夹时发生的情况是,我可以添加一个项目,而且可以多次添加。但是当我转到一个新的食谱添加另一个项目时,它会删除旧的项目并重新启动。
几天来,我一直在复习它,尝试不同的方法,但我还是想不通。
1条答案
按热度按时间oyt4ldly1#
这似乎是共享状态的一个很好的例子。如果您的收藏夹数据是在一个地方管理的,那么在添加、删除或显示时就不会遇到同步问题。
我建议你创造一个环境
然后用上下文提供程序 Package 应用程序的相关部分,例如
在任何需要读取或修改 * 收藏夹 * 的地方,使用上下文挂钩
您还可以使用任何其他形式的状态管理,如Redux。