我正在制作一个食谱应用程序。我希望用户能够将食谱添加到收藏夹列表中。涉及 3 个 React 组件。食谱、添加到收藏夹和收藏夹。
配方组件显示有关所选配方的各种详细信息。
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>
)
}
到目前为止我尝试做的事情:
当我将一项添加到收藏夹时,我可以添加一项,也可以添加多次。但是当我转到新食谱添加另一个项目时,它会删除旧项目并重新启动。
几天来我一直在研究它并尝试不同的事情,但我无法弄清楚。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号
这似乎是共享状态的一个很好的例子。如果您的收藏夹数据在一个位置进行管理,那么在添加、删除或显示时就不会遇到同步问题。
我建议创建一个上下文
import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, } from "react"; const FavoritesContext = createContext({ favorites: [], toggleFavorite: () => {}, isFavorite: () => false, }); // default context value export const FavoritesContextProvider = ({ children }) => { const preloadRef = useRef(false); const [favorites, setFavorites] = useState( JSON.parse(localStorage.getItem("favorites")) ?? [] ); // assuming favourites have IDs const ids = useMemo( () => new Set(favorites.map(({ id }) => id)), [favorites] ); const isFavorite = useCallback((id) => ids.has(id), [ids]); // sync data on change useEffect(() => { // skip initial preload if (preloadRef.current) { localStorage.setItem("favorites", JSON.stringify(favorites)); } preloadRef.current = true; }, [favorites]); const toggleFavorite = ({ id, image, title, route }) => { if (isFavorite(id)) { setFavorites((prev) => prev.filter((fav) => fav.id !== id)); } else { setFavorites((prev) => [...prev, { id, image, title, route }]); } }; return (
      {children}
     
  );
};
// hook helper
export const useFavorites = () => useContext(FavoritesContext);
然后用上下文提供程序包装应用程序的相关部分,例如
只要您需要读取或修改收藏夹,请使用上下文挂钩
// read const { favorites } = useFavorites(); // modify const { isFavorite, toggleFavorite } = useFavorites();您还可以使用任何其他形式的状态管理,例如 Redux。