简体   繁体   English

事件“OnKeyDown”在反应应用程序中仅触发一次

[英]Event “OnKeyDown” fires only once in react app

Hello everyone.大家好。 I am new to web dev.我是网络开发新手。 I just can't understand the problem.我只是无法理解问题所在。 My task is to change the parts of the input (day and month) using a combination of ctr + ArrowUp (increase) and ctr + ArrowDown (decreases).我的任务是使用 ctr + ArrowUp(增加)和 ctr + ArrowDown(减少)的组合来更改输入的部分(日和月)。 Also the variable part is highlighted - this is achieved by tracking the position of the cursor (selectionStart).变量部分也被突出显示 - 这是通过跟踪光标的位置 (selectionStart) 来实现的。 The code works, but for some reason “OnKeyDown” is executed only once and other button presses have no effect.该代码有效,但由于某种原因“OnKeyDown”仅执行一次,其他按钮按下无效。 Why it happens?为什么会发生? How do I make the event “OnKeyDown” work on every combination of buttons pressed?如何使事件“OnKeyDown”对按下的每个按钮组合起作用?

SANDBOX SNIPPET 沙盒片段

My Code我的代码


import React, { useState, useEffect, useRef } from "react";
import styles from "./DataInput.module.css";

const cur_date = new Date();

const DataInput = () => {
  const inputEl = useRef();
  const [selection, setSelection] = useState();
  const [currentDate, newCurrentDate] = useState();

  const date_format = cur_date
    .toLocaleString()
    .replaceAll(".", "/")
    .replace(",", "");

  const [value, setValue] = useState(date_format);

  useEffect(() => {
    if (!selection) return; // prevent running on start
    const { start, end } = selection;
    inputEl.current.focus();
    inputEl.current.setSelectionRange(start, end);
  }, [selection]);

  const keyHandler = (e) => {
    if (e.ctrlKey && e.key === "ArrowUp") {
      e.preventDefault();
      if (
        inputEl.current.selectionStart > 0 &&
        inputEl.current.selectionStart < 2
      ) {
        setSelection({ start: 0, end: 2 });
        const newDay = cur_date.setDate(cur_date.getDate() + 1);
        setValue(
          new Date(newDay)
            .toLocaleString()
            .replaceAll(".", "/")
            .replace(",", "")
        );
      }
      if (
        inputEl.current.selectionStart > 3 &&
        inputEl.current.selectionStart < 5
      ) {
        setSelection({ start: 3, end: 5 });
        const newMonth = cur_date.setMonth(cur_date.getMonth() + 1);
        setValue(
          new Date(newMonth)
            .toLocaleString()
            .replaceAll(".", "/")
            .replace(",", "")
        );
      }
    }
    if (e.ctrlKey && e.key === "ArrowDown") {
      e.preventDefault();
      if (
        inputEl.current.selectionStart > 0 &&
        inputEl.current.selectionStart < 2
      ) {
        setSelection({ start: 0, end: 2 });
        let newDate = cur_date.setDate(cur_date.getDate() - 1);
        setValue(
          new Date(newDate)
            .toLocaleString()
            .replaceAll(".", "/")
            .replace(",", "")
        );
      }
      if (
        inputEl.current.selectionStart > 3 &&
        inputEl.current.selectionStart < 5
      ) {
        setSelection({ start: 3, end: 5 });
        const newMonth = cur_date.setMonth(cur_date.getMonth() - 1);
        setValue(
          new Date(newMonth)
            .toLocaleString()
            .replaceAll(".", "/")
            .replace(",", "")
        );
      }
    }
  };

  const changeHandler = (e) => {
    setValue(e.target.value);
  };

  return (
    <div className={styles.main}>
      <h1> Frontend Task</h1>
      <p id="name">Abramov David</p>
      <input
        ref={inputEl}
        value={value}
        onChange={changeHandler}
        onKeyDown={keyHandler}
      />
    </div>
  );
};

export default DataInput;

I think it's just an issue with some if statements using incorrect index checking and duplication of inputEl.current.selectionStart .我认为这只是一些 if 语句使用不正确的索引检查和inputEl.current.selectionStart重复的inputEl.current.selectionStart

For example:例如:

if (
        inputEl.current.selectionStart > 0 &&
        inputEl.current.selectionStart < 2
   )

Should be something like:应该是这样的:

if (
        inputEl.current.selectionStart >= 0 &&
        inputEl.current.selectionEnd <= 2
   )

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM