guys!
I'am trying to do a prize draw website. I want to fix a date and compare to a live date and show the winner. I'am having a lot of problems when my compare date its equals to my live date, because react dont stop render and call RandomNumber functions a lot of times. I already try to use milliseconds, but sometime react skip it and dont show the winner.
import RandomNumber from "components/RandomNumber";
import { useEffect, useState } from "react";
import "./styles.css";
const Datetime = () => {
const [winner, setWinner] = useState("");
const [dateState, setDateState] = useState(new Date());
let timePrize = "10:33:00";
const datePrize = "12/12/2022";
console.log(winner);
useEffect(() => {
var timer = setInterval(() => setDateState(new Date()), 1000);
return function cleanup() {
clearInterval(timer);
};
});
const currentDate = dateState.toLocaleDateString("pt-BR", {
day: "numeric",
month: "long",
year: "numeric",
});
const currentTime = dateState.toLocaleString("pt-BR", {
hour: "numeric",
minute: "numeric",
second: "numeric",
hour12: true,
});
if (
datePrize === dateState.toLocaleDateString() &&
timePrize === dateState.toLocaleTimeString()
) {
timePrize = "0";
const winner = RandomNumber();
setWinner(winner);
}
return (
<>
<p className="date-custom">{currentDate}</p>
<p className="time-custom">{currentTime}</p>
<div>{winner}</div>
</>
);
};
export default Datetime;
prize draw code:
const RandomNumber = () => {
var items = [
1, 2, 3, 5, 7, 8, 9, 10, 11, 12, 13, 14, 19, 20, 21, 24, 26, 27, 28, 29, 30,
31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 49, 50, 56,
];
let item = items[Math.floor(Math.random() * items.length)];
console.log(typeof item);
const numberToName = (item: number) => {
if (item === 1) {
return `Philipe Jensen ${item}`;
} else if (item === 2) {
return `Jão ${item}`;
} else if (item === 3) {
return `Xepa ${item}`;
} else if (
item === 5 ||
item === 7 ||
item === 10 ||
item === 11 ||
item === 15 ||
item === 19 ||
item === 26 ||
item === 29 ||
item === 30 ||
item === 50
) {
return `Leleo ${item}`;
} else if (item === 8) {
return `Felipe ${item}`;
} else if (item === 9 || item === 21) {
return `Pimpão ${item}`;
} else if (item === 12) {
return `Monteiro ${item}`;
} else if (item === 13) {
return `May ${item}`;
} else if (item === 20) {
return `Bugs ${item}`;
} else if (item === 24 || item === 56) {
return `Vev ${item}`;
} else if (item === 27) {
return `Tic ${item}`;
} else if (item === 28) {
return `Helo Ams ${item}`;
} else if (
item === 31 ||
item === 32 ||
item === 33 ||
item === 34 ||
item === 35 ||
item === 36 ||
item === 37 ||
item === 38 ||
item === 39 ||
item === 40 ||
item === 41 ||
item === 42 ||
item === 43 ||
item === 44 ||
item === 45 ||
item === 46
) {
return `Izumi ${item}`;
} else if (item === 49) {
return `Geobanna ${item}`;
}
};
return numberToName(item) || '';
};
export default RandomNumber;
I want to compare my timePrize and datePrize variable to a live date and show the winner. Thanks!!
CodePudding user response:
Code in your functional component is, as you said, executed on every render. However, the React hook useCallback
https://reactjs.org/docs/hooks-reference.html#usecallback allows you to only execute code when the dependencies of the function change.
For example, see this altered version of your code:
if (
datePrize === dateState.toLocaleDateString() &&
timePrize === dateState.toLocaleTimeString()
) {
timePrize = "0";
const winner = RandomNumber();
setWinner(winner);
}
const isWinner = useCallback(() => {
if (
datePrize === dateState.toLocaleDateString() &&
timePrize === dateState.toLocaleTimeString()
) {
timePrize = "0";
const winner = RandomNumber();
setWinner(winner);
}
}, [dateState]);
useEffect(() => isWinner(), [isWinner]);
This causes function of "winner" check to only recreate itself when the value of dateState
changes, which is once (when you create the original state).
This is combined with a useEffect
, which only runs when it's own dependencies change. Given its only dependency is the new useCallback
function,