I try to convert vanilla javaScript into React but I was unable to get the correct result.
Here is the vanilla javaScript code:)
var minimum = 1;
var maximum = 100;
var int1 = Math.floor(Math.random() * (maximum - minimum + 1)) + minimum;
var int2 = Math.floor(Math.random() * (maximum - minimum + 1)) + minimum;
document.getElementById('question').innerHTML = int1 + " " + "+" + " " + int2;
var qanswer = int1 + int2;
function fire() {
var uanswer = document.getElementById('answer').value;
if (uanswer == qanswer) {
alert("Nice math skills! Refresh the page to play again!");
} else {
alert("WRONG! Don't snooze during math class!")
}
}
This is the React code :)
export default function App() {
const [inputValue, setInputValue ] = useState('')
let minimum = 1;
let maximum = 10;
let int1 = Math.floor(Math.random() * (maximum - minimum + 1)) + minimum;
let int2 = Math.floor(Math.random() * (maximum - minimum + 1)) + minimum;
var qanswer = int1 + int2;
const handleChange = (e) => {
setInputValue(e.target.value)
}
const handleAnswer = () => {
if(qanswer === inputValue) {
alert('You won')
} else {
alert('You lose')
}
}
return (
<div className="App">
<h1>Math Game</h1>
<h2>{`${int1} + ${int2}`}</h2>
<input value={inputValue} onChange={handleChange}/>
<button onClick={handleAnswer}>Answer</button>
</div>
);
}
Now the problem is here when I type the answer in the input field my random number value is changed.
I think you need an extra state. At the moment every time the state changes from a change in input value the component is rerendered, all the calculations are done again, and then that happens again, and again...
So, your target state should maybe an array in which you can store the two numbers you want to check. We place that code in a function which can be called again after the button has been pressed.
We initially call that function from a useEffect hook with an empty dependency array so it only gets called when the component first renders.
In the h2 we join up that array to make a string.
In handleAnswer we add those two elements together to make a total and check that against the (coerced) string from the input.
const { useEffect, useState } = React;
function Example() {
// New state
const [inputValue, setInputValue ] = useState('')
const [ target, setTarget ] = useState([]);
// Function to add to the new state
const newQuestion = () => {
const minimum = 1;
const maximum = 10;
const int1 = Math.floor(Math.random() * (maximum - minimum + 1)) + minimum;
const int2 = Math.floor(Math.random() * (maximum - minimum + 1)) + minimum;
// Set the target as an array of two numbers
setTarget([int1, int2]);
}
// Run the function for the first time
useEffect(() => newQuestion(), []);
const handleChange = (e) => {
setInputValue(e.target.value)
}
const handleAnswer = () => {
// Add up the numbers from the state
const total = target[0] + target[1];
// Check that total against the number
if (total === Number(inputValue)) {
alert('You won');
} else {
alert('You lose');
}
// Call the function again
newQuestion();
}
return (
<div className="App">
<h1>Math Game</h1>
<h2>{target.join(' + ')}</h2>
<input value={inputValue} onChange={handleChange}/>
<button onClick={handleAnswer}>Answer</button>
</div>
);
}
ReactDOM.render(
<Example />,
document.getElementById('react')
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>
<div id="react"></div>