Я делаю калькулятор с помощью React, когда я нажимаю на элементы div, они запускают функцию для обновления состояния, которое переходит в вывод на дисплей калькулятора, у меня нет проблем с этим при нажатии на элементы div. Это код, который работает так, как ожидалось:
const Calculator = () => {
const initialState = {
val: "0",
}
const [value, setValue] = useState(initialState);
const sendCharacter = (number) =>{
let str = number.toString();
if (value.val != "0") {
const conc = value.val.concat(str);
setValue({
val: conc
});
} else {
setValue({
val: str
});
}
};
return (
<div id='calculator'>
<div id='display'>{value.val}</div>
<div id='one' className='numbers keys' onClick = {() => sendCharacter(1)}>1</div>
</div>
);
Теперь я хочу сделать то же самое, но вместо того, чтобы нажимать div id="one", чтобы добавить "единицы" в свое состояние, я хочу, чтобы эти единицы добавлялись в состояние, когда я нажимаю клавишу 1
. Я добавил EventListener через useEffect()
, который загружается только один раз после первоначального рендеринга. Когда я нажимаю 1
, он вызывает ту же самую функцию с тем же аргументом, который вызывается при нажатии sendCharacter(1)
, вот мой код:
useEffect(() => {
console.info("useEffect");
document.addEventListener("keyup", detectKey, true);
}, []);
const detectKey = (e) => {
if (e.key == "1") {
sendCharacter(1)
}
};
Однако, когда я нажимаю клавишу i
, я могу обновить состояние только в первый раз, если я пытаюсь добавить вторую цифру к моему номеру, это действует так, как если бы мое фактическое состояние было «0» вместо «1», что не не позволять ему входить в оператор if.
Чтобы быть ясным и кратким: если щелкнуть мой div id="one", я могу ввести первое условие моего оператора if и обновить val
через мою переменную conc, если я сделаю это, нажав клавишу i
, он всегда введет оператор else.
if (value.val != "0") {
const conc = value.val.concat(str);
setValue({
val: conc
});
} else {
setValue({
val: str
});
}
Я пробовал регистрировать сообщения везде и посмотреть, совпадает ли мой аргумент «1» с помощью щелчка или нажатия моей клавиши, они отправляют одно и то же значение, я полностью потерялся здесь и расстроен, потому что у меня есть более 1 часа пытаясь понять, что происходит. Кроме того, я проверил, рендерится ли компонент, прежде чем нажимать клавишу, чего не было.
Кстати, извините за мой английский, а не мой родной язык, если кто-то может мне помочь и нуждается в разъяснении по одной части, я отвечу как можно скорее, заранее спасибо.
Кажется, вы попадаете в ловушку замыканий. Попробуйте обновить код sendCharacter
следующим образом.
const sendCharacter = (number) =>{
let str = number.toString();
setValue(value => {
if (value.val != "0") {
const conc = value.val.concat(str);
return {
val: conc
};
} else {
return {
val: str
};
}
});
};
Большое спасибо, нужно вернуться к моим основам.