簡體   English   中英

如何使用反應鈎子 useState 從 API 向對象添加屬性

[英]How to add property to an object from an API using react hooks useState

我正在嘗試在我的膳食食譜網站https://recipa.netlify.app/ 中為書簽膳食切換真或假。 這是我切換書簽真假的邏輯。

如何替換 data.meals[0].bookmarked = true; 帶有 setState 邏輯的邏輯,以便頁面在每次 data.meals[0].bookmarked 設置為 true 或 false 時重新呈現

我正在嘗試將名為 booknamed 的新屬性設置為從 API 獲取的對象

// data.meals[0] is coming from  the API. 
useEffect(
    () =>
      doFetch('https://www.themealdb.com/api/json/v1/1/lookup.php?i=${mealID}'),
    [doFetch, mealID, data]
  );

// Logic to check if current meal loaded is currently also in bookmarks
// if it is in bookmarks, mark meal as bookmarked, else mark as not bookmarked.
// This logic works fine but because I use data.meals[0].bookmarked 
// instead of setState, the page doesn't rerender to make the change from true or false.
if (
  Bookmarks.some(
    (bookmark) => bookmark.idMeal === data.meals[0].idMeal
  )
) {
  data.meals[0].bookmarked = true;
} else {
  data.meals[0].bookmarked = false;
}

// If data.meals[0].bookmarked is true(i.e meal is in bookmarks) call deleteBookmark 
// else call addBoomark function
render () {
            <button onClick>={
                    data.meals[0].bookmarked === true
                    
                      ? () => deleteBookmark(data.meals && 
                      data.meals[0])
                  
                      : () => addBookmark(data.meals && 
                     data.meals[0])
                  }}
            </button>
       }
 // onClick of Bookmark button calls persistBookmarks to update 
 // and save the changes made by addBookmark or 
 // deleteBookmark to bookmarks in localStorage

 // whenever persistsbookmarks() makes an update to bookmarks 
 // stored in local storage, setStoredBookmarks will get the 
 // updated bookmarks in local storage and rerender

 // The changes in state of storedBookmarks then causes a 
 // rerender of the page which then applies the changes made  
 // to data.meals.bookmarked state

 // Changes in data.meals.bookmarked state is what calls either  
 // addBookmarks or removeBookmarks

  const persistBookmarks = function () {
    localStorage.setItem('bookmarks', JSON.stringify(bookmarks));
  };   

  const addBookmark = function (recipe) {

    // Add bookmark
    bookmarks.push(recipe);

    // Mark current recipe as bookmarked
    if (data && recipe.idMeal === data.meals[0].idMeal) {
      data.meals[0].bookmarked = true;
      setBookmarked(true);

    }

    persistBookmarks();
  };

  const deleteBookmark = function (recipe) {

    // Delete bookmark
    const index = bookmarks.findIndex((el) => el.idMeal === recipe.idMeal);
    bookmarks.splice(index, 1);

    // Mark current recipe as NOT bookmarked
    if (data && recipe.idMeal === data.meals[0].idMeal) {
      data.meals[0].bookmarked = false;
      setBookmarked(false);
    }

    persistBookmarks();
  };


 // storedBookmarks will be set to bookmarks in Local Storage
 const [storedBookmarks, setStoredBookmarks] = useState([]);

  // check if storedBookmarks has changed state
  // if so, then call checkBookmark
  
  useEffect(() => {
    if (storedBookmarks && data) {
      checkBookmark();
    }
  });

 // on Page Load I setStoredBookmarks to get new meal added to Local storage
  useEffect(() => {
    setStoredBookmarks(JSON.parse(localStorage.getItem('bookmarks')));
  }, [bookmarks]);

  // When CheckBookMark is called, data.meals[0].bookmarked is
  // either set to true or false
  // This checkBookmark will be called everytime StoredBookmarks
  // i.e new meals are added to bookmarks in Local Storage


  const checkBookmark = () => {
    if (
      storedBookmarksCheck &&
      storedBookmarksCheck.some(
        (bookmark) => bookmark.idMeal === data.meals[0].idMeal
      )
    ) {
      data.meals[0].bookmarked = true;
    } else {
      data.meals[0].bookmarked = false;
    }
  };

  // onPageLoad and whenever data is available from the api
  // useEffect checks if data.meals[0].bookmarked === true or 
  // false
  // then setBookmarked(true or false)
  // which then causes a rerender and 
  // makes the changes of data.meals[0].bookmarked to false

  useEffect(() => {
    if (data && data.meals[0].bookmarked === true) {
      setBookmarked(true);
    } else if (data && data.meals[0].bookmarked === false) {
      setBookmarked(false);
    }
  }, [data]);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM