Home > Blockchain >  UseEffect running perfectly on first try, but fails after refreshing twice
UseEffect running perfectly on first try, but fails after refreshing twice

Time:08-09

The code runs perfectly when refreshing once, but when refreshing twice, it resets the money and luck to 1 and 10 which are the default values. Anyone know how this can be fixed? The first useEffect is for getting the user's data, and the second is for saving when money or luck changes.

const [luck, setLuck] = useState(1);
const [money, setMoney] = useState(10);
useEffect(() => {
    const getUser = async () => {
      const res = await fetch(`/api/email/${session?.user?.email}`, {
        method: "GET",
        headers: {
          "Content-Type": "application/json",
          Authorization: "tmthisdumb123",
        },
      });
      const data = await res.json();
      setName(data.name);
      setLuck(data.luck);
      setEmail(data.email);
      setMoney(data.money);
      if (data.rarity && data.quality && data.rarity !== "Unknown") {
        setRarity(data.rarity);
        setQuality(data.quality);
        setLevel(data.level);
        setMold(data.mold);
        setEnchant1(data.enchant1);
        setEnchant2(data.enchant2);
        setEnchant3(data.enchant3);
        setEnchantName1(data.enchantName1);
        setEnchantName2(data.enchantName2);
        setEnchantName3(data.enchantName3);
        setID(data.swordId);
        setValue(
          CalculateRarityValue(data.rarity) *
            CalculateQualityValue(data.quality) *
            CalculateMoldValue(data.mold) *
            (CalculateLevelValue(data.level) * 7.5) *
            CalculateEnchant(data.enchant1) *
            CalculateEnchant(data.enchant2) *
            CalculateEnchant(data.enchant3) *
            EnchantPower(data.enchant1) *
            EnchantPower(data.enchant2) *
            EnchantPower(data.enchant3) *
            CalculateRaritySuffix(data.rarity) *
            20
        );
        setSold(false);
        setGeneratable(true);
      }
      return { user: data };
    };
    getUser();
  }, []);
  // Save the users data everytime luck or money changes
  const saveUser = async () => {
    await fetch(`/api/email/${session?.user?.email}`, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        Authorization: "tmthisdumb123",
      },
      body: JSON.stringify({
        luck: luck,
        money: money,
      }),
    });
  };
  useEffect(() => {
    saveUser();
  }, [money, luck]);

This code is supposed to first get the user's data, then use Setters to set the money, luck, etc. Then it checks if there are changes with the money and/or luck, if so it will push them to the API, then through the database.

CodePudding user response:

From comments discussion: Error is due to 2 useEffects are fired on page initial render, one to get the data from /api/email/${session?.user?.email} and one to update/save data when [money, luck] changed. Due to they were both fired on first render - getUser returned and set values from api/db, then saveUser updated data with defaults from useStates and now React App has a valid data and db data is corrupted.

Solution:

  1. add const [isLoaded, setIsLoaded] = useState(false);

  2. add setIsLoaded(true); just before the return return { user: data }; from getUser method.

  3. Modify saveUser hook to

useEffect(() => {
  if (!isLoaded) return;
  saveUser();
}, [isLoaded, money, luck]);

  • Related