如何不可变地更新数组并将其存储在 React 的本地存储中?
P粉604669414
P粉604669414 2024-04-02 09:51:18
[JavaScript讨论组]

我正在制作一个食谱应用程序。我希望用户能够将食谱添加到收藏夹列表中。涉及 3 个 React 组件。食谱、添加到收藏夹和收藏夹。

配方组件显示有关所选配方的各种详细信息。

AddToFavorites 组件是一个在 Recipe 组件中呈现的按钮。

收藏夹组件是一个列表,显示使用“添加到收藏夹”按钮添加到收藏夹的所有项目。

function Favorites() {
  const [favList, setFavList] = useState(localStorage.getItem('favorites'));
  return (
    
      {favList}
      {favList.map(listItem => {
        
  • {listItem}
  • })}
    ) }
    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 (
        
            

    {details.title}

    {activeTab === 'instructions' && (

    )} {activeTab === 'ingredients' && (
      {details.extendedIngredients && details.extendedIngredients.map((ingredient) => (
    • {ingredient.original}
    • ))}
    )} {activeTab === 'summary' && (

    )}
    ) }
    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 (
      
          {!active ? 'Add to favorites' : 'Remove from favorites'}
          
    ) }

    到目前为止我尝试做的事情:

    • 将 API 数据作为 Recipe 中的“details”属性传递到 AddToFavorites。
    • 在 AddToFavorites 中将收藏夹设置为默认为空数组的状态。
    • 在AddToFavorites中添加onClick事件以添加到收藏夹btn,该事件调用AddToFavorites()函数。
    • 在 AddToFavorites() 函数中,我尝试通过使用展开运算符并将收到的详细信息道具(具有 API 数据)作为新项目添加到状态数组的新副本中,来永久更新收藏夹状态,然后将其存储在本地存储中。

    当我将一项添加到收藏夹时,我可以添加一项,也可以添加多次。但是当我转到新食谱添加另一个项目时,它会删除旧项目并重新启动。

    几天来我一直在研究它并尝试不同的事情,但我无法弄清楚。

    P粉604669414
    P粉604669414

    全部回复(1)
    P粉054616867

    这似乎是共享状态的一个很好的例子。如果您的收藏夹数据在一个位置进行管理,那么在添加、删除或显示时就不会遇到同步问题。

    我建议创建一个上下文

    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。

    热门教程
    更多>
    最新下载
    更多>
    网站特效
    网站源码
    网站素材
    前端模板
    关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
    php中文网:公益在线php培训,帮助PHP学习者快速成长!
    关注服务号 技术交流群
    PHP中文网订阅号
    每天精选资源文章推送
    PHP中文网APP
    随时随地碎片化学习

    Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号