Rumah > Soal Jawab > teks badan
Saya sedang membuat aplikasi resipi. Saya mahu pengguna dapat menambah resipi pada senarai kegemaran. Terdapat 3 komponen React yang terlibat. Resipi, tambah pada kegemaran dan kegemaran.
Komponen resipi memaparkan pelbagai butiran tentang resipi yang dipilih.
Komponen AddToFavorites ialah butang yang diberikan dalam komponen Resipi.
Komponen Kegemaran ialah senarai yang memaparkan semua item yang ditambahkan pada kegemaran menggunakan butang "Tambah ke Kegemaran".
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> ) }
Apa yang saya cuba setakat ini:
Apabila saya menambah item pada kegemaran, saya boleh menambah satu item atau beberapa kali. Tetapi apabila saya pergi ke resipi baru dan menambah item lain, ia memadamkan item lama dan dimulakan semula.
Saya telah menelitinya selama beberapa hari dan mencuba pelbagai perkara tetapi saya tidak dapat memahaminya.
P粉0546168672024-04-03 09:03:17
Ini nampaknya contoh yang baik bagi keadaan yang dikongsi. Jika Kegemarandata anda diurus di satu tempat, anda tidak akan menghadapi masalah penyegerakan apabila menambah, memadam atau memaparkan.
Saya syorkan mencipta konteks
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);
Kemudian bungkus bahagian aplikasi yang berkaitan dengan penyedia konteks, seperti
Apabila anda perlu membaca atau mengubah suai kegemaran, gunakan cangkuk konteks
// read const { favorites } = useFavorites(); // modify const { isFavorite, toggleFavorite } = useFavorites();
Anda juga boleh menggunakan sebarang bentuk pengurusan negeri lain, seperti Redux.