Невозможно обновить состояние в React через ключевое событие

Я делаю калькулятор с помощью 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 часа пытаясь понять, что происходит. Кроме того, я проверил, рендерится ли компонент, прежде чем нажимать клавишу, чего не было.

Кстати, извините за мой английский, а не мой родной язык, если кто-то может мне помочь и нуждается в разъяснении по одной части, я отвечу как можно скорее, заранее спасибо.

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
69
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
            };
        }
    });
  };

Большое спасибо, нужно вернуться к моим основам.

David98761324 11.02.2023 04:44

Другие вопросы по теме