Reputation: 31
I'm new in React and maybe my logic here i a mess: I have Game component and it has 2 childs: Board and Timer.
The Board have a button to start the game. When i start the game, i want to start the timer. There is a way to call directly the function to start the timer, from Board? I tried to send a function to Board from Game and that function changes some states in Game, but i don't know how to trigger the startStopTime() of Timer (my idea was use useEffect() but i don't know if there is a more easy way)
Thanks for your help
Game.jsx
function Game(){
return(
<div>
<Board>
<Timer>
</div>
)
}
Board.jsx
function Board(){
/* logic game*/
return (
<Button>Start game</button>
)
}
timer.jsx
function Timer(){
/* methods timer*/
function startStopTime{ /* code*/}
function resetTimer{ /* code*/}
return (
<div>{timeRunningGame}</div>
)
}
Upvotes: 1
Views: 238
Reputation: 202618
I think you were on the right track thinking to use an effect in Timer
.
Here's an implementation, others exist.
Timer.jsx
const Timer = ({ isRunning, onReset }) => {
const [time, setTime] = useState(0);
useEffect(() => {
const timer = isRunning
// if true, start timer
? setInterval(() => setTime(t => t + 0.1), 100)
// else reset time back to 0
: setTime(0);
// provide cleanup function
return () => clearInterval(timer);
}, [isRunning]);
return (
<>
<div>{Number(time).toFixed(1)}</div>
{isRunning && (
<button type="button" onClick={onReset}>
Reset
</button>
)}
</>
);
};
Board.jsx takes an onStartGame
callback function
const Board = ({ onStartGame }) => {
/* game logic */
return (
<button type="button" onClick={onStartGame}>
Start Game
</button>
);
};
Game.jsx Manages state of timer being started and passed
const Game = () => {
const [isRunning, setIsRunning] = useState(false);
const runTimer = run => () => setIsRunning(run);
return (
<>
<Board onStartGame={runTimer(true)} />
<Timer isRunning={isRunning} onReset={runTimer(false)} />
</>
);
};
Upvotes: 1