Estou construindo um aplicativo React simples onde tenho um pet com propriedades como fome, tédio e energia. Quero atualizar essas propriedades em intervalos diferentes (fome a cada 5 segundos, tédio a cada 8 segundos e energia a cada 10 segundos).
No entanto, enquanto o status de fome atualiza corretamente, os status de tédio e energia não. Estou usando setInterval
para atualizar esses valores, mas parece que apenas a fome está sendo atualizada.
Aqui está o código relevante:
import { useEffect, useState } from "react";
import { Pet } from "./types/pet";
function App() {
const [pet, setPet] = useState<Pet | null>(null);
useEffect(() => {
// Load pet from localStorage or create a new pet
const savedPet = localStorage.getItem("pet");
if (savedPet) {
try {
const parsedPet = JSON.parse(savedPet) as Pet;
setPet(parsedPet);
} catch (error) {
console.error("Error parsing saved pet:", error);
createNewPet();
}
} else {
createNewPet();
}
}, []);
const updatePet = (updateFn: (currentPet: Pet) => Partial<Pet>) => {
setPet((prevPet) => {
if (!prevPet) return null;
const updatedPet = { ...prevPet, ...updateFn(prevPet) };
localStorage.setItem("pet", JSON.stringify(updatedPet));
return updatedPet;
});
};
useEffect(() => {
if (!pet) return;
const hungerInterval = setInterval(() => {
updatePet((pet) => ({ hunger: Math.min(pet.hunger + 1, 100) }));
}, 5000);
const boredomInterval = setInterval(() => {
updatePet((pet) => ({ boredom: Math.min(pet.boredom + 1, 100) }));
}, 8000);
const energyInterval = setInterval(() => {
updatePet((pet) => ({ energy: Math.max(pet.energy - 1, 0) }));
}, 10000);
return () => {
clearInterval(hungerInterval);
clearInterval(boredomInterval);
clearInterval(energyInterval);
};
}, [pet]);
return (
<div>
<p>Hunger: {pet.hunger}%</p>
<p>Boredom: {pet.boredom}%</p>
<p>Energy: {pet.energy}%</p>
</div>
);
}
export default App;
O que estou vivenciando:
- A estatística de fome é atualizada corretamente a cada 5 segundos.
- As estatísticas de tédio e energia não são atualizadas como esperado, embora seus intervalos sejam configurados da mesma maneira.
O que eu tentei:
- Verifiquei os intervalos e eles parecem estar corretos.
- Tentei atualizar o estado com atualizações funcionais para garantir que o estado mais recente fosse usado, mas ainda assim, apenas atualizações de fome.
Alguém sabe por que somente a estatística de fome está sendo atualizada e o que posso fazer para corrigir isso?
Cada vez que você atualiza o pet (a primeira vez seria em resposta à mudança de fome, já que esse é o intervalo mais curto), o useEffect limpará todos os intervalos e os redefinirá (e então o próximo a ser acionado será a fome novamente).
Você quer que o useEffect seja executado somente quando um pet diferente for usado, em vez de sempre que o pet atual sofrer uma mudança de status. Então ter [pet] no array de dependências é o problema. Como @pmoleri afirmou, um id (ou um nome) que não muda por pet seria o caminho a seguir -
[pet?.id]
ou[pet?.name]
. Se apenas um pet for suportado no total, você pode usar um array de dependências vazio.Você está atualizando o objeto pet, mas também diz que pet é uma dependência do useEffect
Você deve fazer assim para registrar todos os seus intervalos apenas uma vez, e dentro deles, você verifica se o animal de estimação existe ou não
Isso até permitiria que você removesse a verificação de existência do animal de estimação e mesclasse ambos os seus useEffect