事件“OnKeyDown”在 React 应用程序中仅触发一次
Event “OnKeyDown” fires only once in react app
大家好。我是网络开发新手。我只是不明白这个问题。我的任务是使用 ctr + ArrowUp(增加)和 ctr + ArrowDown(减少)的组合来更改输入的部分(日和月)。可变部分也被突出显示 - 这是通过跟踪光标的位置 (selectionStart) 实现的。该代码有效,但由于某种原因,“OnKeyDown”仅执行一次,其他按钮按下无效。为什么会这样?如何使事件“OnKeyDown”在按下的每个按钮组合上起作用?
我的代码
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;
我认为这只是一些 if 语句使用不正确的索引检查和 inputEl.current.selectionStart
重复的问题。
例如:
if (
inputEl.current.selectionStart > 0 &&
inputEl.current.selectionStart < 2
)
应该是这样的:
if (
inputEl.current.selectionStart >= 0 &&
inputEl.current.selectionEnd <= 2
)
大家好。我是网络开发新手。我只是不明白这个问题。我的任务是使用 ctr + ArrowUp(增加)和 ctr + ArrowDown(减少)的组合来更改输入的部分(日和月)。可变部分也被突出显示 - 这是通过跟踪光标的位置 (selectionStart) 实现的。该代码有效,但由于某种原因,“OnKeyDown”仅执行一次,其他按钮按下无效。为什么会这样?如何使事件“OnKeyDown”在按下的每个按钮组合上起作用?
我的代码
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;
我认为这只是一些 if 语句使用不正确的索引检查和 inputEl.current.selectionStart
重复的问题。
例如:
if (
inputEl.current.selectionStart > 0 &&
inputEl.current.selectionStart < 2
)
应该是这样的:
if (
inputEl.current.selectionStart >= 0 &&
inputEl.current.selectionEnd <= 2
)