I'm building a react-app that rolls a dice in a certain interval, shows all the latest rolls and lets the user try to guess the next throw (just to give a simple idea).
I'll try to give you an overview of the important parts of my code. First the main view: (and here is a working example https://codesandbox.io/s/spring-sound-ydcevo?file=/src/App.js)
import React, { useState, useRef } from "react";
import DiceComponent from "./dice-component";
function View() {
const [dice, setDice] = useState(0);
const diceRef = useRef(null);
return (
<div>
<DiceComponent setDice={setDice} diceRef={diceRef} dice={dice} />
current throw: {dice}
</div>
);
}
export default View;
and the dice component:
import Dice from "react-dice-roll";
import React, { useEffect } from "react";
function DiceComponent({ diceRef, setDice, dice }) {
const roll = () => {
getRoll();
rollDice();
};
const getRoll = () => {
let diceRoll = Math.floor(Math.random() * 5) + 1;
setDice(diceRoll);
};
const rollDice = () => {
if (diceRef && diceRef.current) {
diceRef.current.style.pointerEvents = "auto";
diceRef.current.children[0].click();
diceRef.current.style.pointerEvents = "none";
}
};
useEffect(() => {
const interval = setInterval(() => {
roll();
}, 3500);
return () => clearInterval(interval);
}, [dice, diceRef]);
return (
<div>
<div ref={diceRef} style={{ pointerEvents: "none" }}>
<Dice size={100} cheatValue={dice} key={"dice"} />
</div>
</div>
);
}
export default DiceComponent;
And to give a quick explanation about the dice. I fetch a roll number from my BE with the fetch as you can see. The dice is supposed to show this fetched number (the dice var) after I roll it. This is possible with the cheatValue={dice}
, which lets the dice always roll to the given number of cheatValue
. After I fetch and set my variables, I want to roll the dice. I achieve this with useRef
and calling a click with it.
Normally the dice would only roll if it gets clicked. But because the dice is not supposed to be clicked, but rather just spin on its own, I create a custom click event to trigger the roll.
Everything works fine so far, but I have one problem, that i can't seem to fix. In the main view I display the current dice for testing and it shows that my dice component always rolls the last dice number and not the current one. So it's always one behind, but I want it to always throw the actual current dice number that was fetched.
I tried to put the useEffect
and all the fetch and roll method into my main view, but that didn't change anything.
I use useEffect
because I had the problem, that my fetch call was always called multiple times, which messed up my project. Thats why I need useEffect
.
Any questions, or ideas on how I can achieve this? My project is a lot bigger than this part that I'm showing, so I hope I got the problem out. If something is not clear please tell me.