Heim  >  Fragen und Antworten  >  Hauptteil

Wie aktualisiere ich ein Array unveränderlich und speichere es im lokalen Speicher in React?

Ich mache eine Rezept-App. Ich möchte, dass der Benutzer Rezepte zu einer Favoritenliste hinzufügen kann. Es sind 3 React-Komponenten beteiligt. Rezepte, zu Favoriten und Favoriten hinzufügen.

Recipe-Komponente zeigt verschiedene Details zum ausgewählten Rezept an.

Die AddToFavorites-Komponente ist eine Schaltfläche, die innerhalb der Recipe-Komponente gerendert wird.

Die Komponente „Favoriten“ ist eine Liste, die alle Elemente anzeigt, die über die Schaltfläche „Zu Favoriten hinzufügen“ zu den Favoriten hinzugefügt wurden.

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>
)
}

Was ich bisher versucht habe:

Wenn ich einen Artikel zu meinen Favoriten hinzufüge, kann ich einen Artikel oder mehrere Male hinzufügen. Aber wenn ich zu einem neuen Rezept gehe und einen weiteren Artikel hinzufüge, wird der alte Artikel gelöscht und neu gestartet.

Ich habe ein paar Tage damit verbracht und verschiedene Dinge ausprobiert, aber ich komme nicht dahinter.

P粉604669414P粉604669414182 Tage vor317

Antworte allen(1)Ich werde antworten

  • P粉054616867

    P粉0546168672024-04-03 09:03:17

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

    我建议创建一个上下文

    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。

    Antwort
    0
  • StornierenAntwort