I am learning React Hooks, and I wanna to build a type race game: a mini game to track how quickly you can type out a snippet of text.
The logic is simple: When user starts the game, set the start time
, and when the value
of the input equals the chosen snippet
, display the endTime
.
But when I start the game and input the correct words, it doesn't show that I have input the same words.
Open the console, input any words, and I found that react did not capture the last letter I have input, for example, I input abc
, the console just show me ab
.
So how can I use react hooks to complete the game?
Here is my whole code:
const App = () => {
const SNIPPETS = [
'Bears, beets, battlestar galactica',
"What's Forrest Gump's password? 1Forrest1",
'Where do programmers like to hangout? The Foo Bar'
]
const INITIAL_GAME_STATE = { victory: false, startTime: null, endTime: null }
const [snippet, setSnippet] = useState('')
const [gameState, setGameState] = useState(INITIAL_GAME_STATE)
const [userText, setUserText] = useState('')
useEffect(() => {
console.log('change')
if (gameState.victory) {
document.title = gameState.victory ? 'Victory!' : 'Playing...'
}
}, [gameState.victory])
const updateUserText = e => {
setUserText(e.target.value)
console.log(snippet)
console.log(userText)
if (userText === snippet) {
console.log('same')
setGameState({
...gameState,
victory: true,
endTime: new Date().getTime() - gameState.startTime
})
}
}
const chooseSnippet = snippetIndex => () => {
setSnippet(SNIPPETS[snippetIndex])
setGameState({
...gameState,
startTime: new Date().getTime()
})
}
return (
<div className="game-wrapper">
<h2>Type Race</h2>
{ snippet && (
<>
<h4>{ snippet }</h4>
<input type="textarea" value={ userText } onChange={ updateUserText } />
<br />
</>
) }
<br/>
<button onClick={ chooseSnippet(0) }>Start a new race!</button>
<br/>
{ gameState.victory && (
<h4>`Done! <span></span>Time: ${ gameState.endTime }ms`</h4>
) }
<br/>
{
SNIPPETS.map((SNIPPET, index) => (
<button onClick={ chooseSnippet(index) } key={ index }>
{ SNIPPET.substring(0, 10) }...
</button>
))
}
</div>
)
}