I am developing the game app with React + Typescript. When i refactored the App component from ClassComponent to FC, i had to use UseEffect Hook for implementing the ComponentDidMount method here. Then i had to call the function compareNumbers() when the one of the fields of state changes. Here is the problem. when i use useEffect only for mounting, the number I entered doesn't changes even when I write the state chengin in the callback. When I use UseEffect for calling comparing function, but leave the mounting, i don`t get number generation. But when I use both of them, nothin works, no number generation and no setting the number from input. And when i restart the gae by startNewGame(), number generates correctly and sets the state...
full code here: https://github.com/mykola-kolomoyets/cow-bull-react-ts
Here is fragment of code:
interface IAppState {
moves: number
currentNumber: number
enteredNumber: number
gameData: {
cows: number
bulls: number
}
incorrectNumbers: number[]
warnings: string[]
};
const App: FC = () => {
const [data, setData] = useState<IAppState>(
{
moves: 0,
currentNumber: 0,
enteredNumber: 0,
gameData: {
cows: 0,
bulls: 0
},
incorrectNumbers: [],
warnings: []
});
// useEffect(() => {
// generateNumber();
// }, []);
// useEffect(() => {
// compareNumbers();
// }, [data.enteredNumber])
const handleCallBack = async (childData: number): Promise<void> => {
console.log("translating the number to App");
await setData({...data, enteredNumber: childData});
}
const generateNumber = (): void => {
let digits: number[] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
let arr: number[] = [];
for (let i = 0; i < 4; i++) {
let index = Math.floor(Math.random() * digits.length);
if (i === 0 && index === 0) index++;
arr.push(digits[index]);
digits.splice(index, 1);
}
setData({
...data,
currentNumber: +arr.join(''),
incorrectNumbers: digits
});
}
...
const startNewGame = (): void => {
setData({
moves: 0,
currentNumber: 0,
enteredNumber: 0,
gameData: {
cows: 0,
bulls: 0
},
incorrectNumbers: [],
warnings: []
});
generateNumber();
}
return (
<>
<h1>Cow-Bull game</h1>
<h3>React+Typescript version</h3>
<Moves moves={data.moves} />
<NumInput parentCallBack={handleCallBack} />
<button onClick={startNewGame}>restart game</button>
<WarningsContainer warnings={data.warnings} />
<CowBulls cows={data.gameData.cows} bulls={data.gameData.bulls} />
</>
)
}
useCallbackuseEffect(() => { generateNumber(); }, []); useCallback(() => { compareNumbers(); }, [data.enteredNumber])