访问表单输入元素的onChange事件

huangapple go评论54阅读模式
英文:

Accesing form input element onChange

问题

我想要能够在keydown和鼠标点击事件中都能选择radio按钮。但是我在同一个函数中无法访问keydown事件和鼠标点击事件的两个event参数。因此,我无法在keydown事件中更新状态来存储选择的值,但在鼠标点击事件中可以访问输入事件参数。

以下是代码:

import { useState, useEffect, useRef } from "react";
import { useLocation } from "react-router-dom";

import { englishQuestions } from "../questions/englishQ";

const English = () => {
  // ... 省略了一些代码

  // 这是我无法访问`keydown`事件的`onChange`函数
  const handleChange = (e: any) => {
    // ... 省略了一些处理逻辑
  };

  const submit = (e: any) => {
    e.preventDefault();
    // ... 省略了一些提交逻辑
  };

  // 这里是事件监听器的调用
  useEffect(() => {
    document.body.addEventListener("keydown", handleChange);
  }, [input]);

  return (
    <>
      <div className="bg-gray-200 mx-auto my-10 w-3/4 p-10 shadow-sm shadow-gray-600 rounded-lg">
        <form onSubmit={submit} className="mb-10">
          {englishQuestions.map((question) => {
            // ... 省略了一些循环逻辑
          })}
          <div className="flex justify-center">
            <button
              type="submit"
              name="submit"
              className="btnExam p-3 mx-auto cursor-pointer"
            >
              Submit
            </button>
          </div>
        </form>
      </div>
    </>
  );
};

export default English;

请注意,上面的代码只是提取了与翻译请求相关的部分。如果您需要更多的帮助或解释,请随时提问。

英文:

I want to be able to select a radio button onChange viakeydown and mouse click. But I am having trouble accessing both event parameters of the on keydown and on mouse click in the same function. So can't update my state to store selected value on keydown but it works on mouse click because I can access the input event parameter on mouse click.

Here is the code.

import { useState, useEffect, useRef } from &quot;react&quot;;
import { useLocation } from &quot;react-router-dom&quot;;
import { englishQuestions } from &quot;../questions/englishQ&quot;;
const English = () =&gt; {
const theRef = useRef();
const { state } = useLocation();
const { user } = state;
const [input, setInputs] = useState&lt;{ [key: string]: string }[]&gt;([]);
const [answersSelected, setAnswersSelected] = useState({});
const [selected, setSelected] = useState&lt;{ [key: string]: boolean }&gt;({});
const [submitted, setSubmitted] = useState(false);
const [keyCode, setKeyCode] = useState(&quot;&quot;);
var index1 = 0;
const answers = englishQuestions.map((items, index) =&gt; items.answer);
//This is the `onChange` `function` from which I can&#39;t access `keydown` event
const handleChange = (e: any) =&gt; {
const numbers = /\d+/g;
switch (e.code) {
case &quot;keyA&quot;:
setKeyCode(&quot;keyA&quot;);
const { value, name } = e.target;
const currentQuestionNumber = name.slice(name.indexOf(&quot;englishQ&quot;), 10);
const currentQuestion = name.slice(name.indexOf(&quot;:&quot;) + 2);
const currentArrayIndex = name.match(numbers)[0] - 1;
if (answers[currentArrayIndex] === value) {
setInputs([
...input,
{
questionNumber: currentQuestionNumber.trim(),
question: currentQuestion,
answer: value,
status: &quot;correct&quot;,
marks: &quot;2&quot;,
},
]);
setAnswersSelected({ ...answersSelected, [name]: value });
} else {
setInputs([
...input,
{
questionNumber: currentQuestionNumber.trim(),
question: currentQuestion,
answer: value,
status: &quot;wrong&quot;,
marks: &quot;0&quot;,
},
]);
setAnswersSelected({ ...answersSelected, [name]: value });
}
//detect if an answer was selected
setSelected({ ...selected, [currentArrayIndex + 1]: true });
//convert the answered object keys into an array
const submittedKeys = Object.keys(selected);
//check if all answers were selected
const checkSelelction = submittedKeys.filter(
(key, index) =&gt; selected[key] === true
);
if (checkSelelction.length + 1 &gt;= 10) {
setAllSelected(true);
} else {
setAllSelected(false);
}
break;
case &quot;keyB&quot;:
setKeyCode(&quot;keyB&quot;);
break;
case &quot;keyC&quot;:
setKeyCode(&quot;keyC&quot;);
break;
case &quot;keyD&quot;:
setKeyCode(&quot;keyD&quot;);
break;
default:
setKeyCode(&quot;&quot;);
}
setSelectedValue([...selectedValue, { theSelectedValue: e.target.value }]);
localStorage.setItem(&quot;theSelectedValue&quot;, JSON.stringify(selectedValue));
console.log(localStorage.getItem(&quot;theSelectedValue&quot;) as string);
const { value, name } = e.target;
const currentQuestionNumber = name.slice(name.indexOf(&quot;englishQ&quot;), 10);
const currentQuestion = name.slice(name.indexOf(&quot;:&quot;) + 2);
const currentArrayIndex = name.match(numbers)[0] - 1;
if (answers[currentArrayIndex] === value) {
setInputs([
...input,
{
questionNumber: currentQuestionNumber.trim(),
question: currentQuestion,
answer: value,
status: &quot;correct&quot;,
marks: &quot;2&quot;,
},
]);
setAnswersSelected({ ...answersSelected, [name]: value });
} else {
setInputs([
...input,
{
questionNumber: currentQuestionNumber.trim(),
question: currentQuestion,
answer: value,
status: &quot;wrong&quot;,
marks: &quot;0&quot;,
},
]);
setAnswersSelected({ ...answersSelected, [name]: value });
}
//detect if an answer was selected
setSelected({ ...selected, [currentArrayIndex + 1]: true });
//convert the answered object keys into an array
const submittedKeys = Object.keys(selected);
//check if all answers were selected
const checkSelelction = submittedKeys.filter(
(key, index) =&gt; selected[key] === true
);
if (checkSelelction.length + 1 &gt;= 10) {
setAllSelected(true);
} else {
setAllSelected(false);
}
};
const submit = (e: any) =&gt; {
e.preventDefault();
setSubmitted(true);
localStorage.setItem(&quot;studentId&quot;, JSON.stringify(user.studentId));
localStorage.setItem(&quot;englishSubmitted&quot;, &quot;true&quot;);
localStorage.setItem(&quot;englishAnswers&quot;, JSON.stringify(input));
};
//Here is the call to the event listener
useEffect(() =&gt; {
document.body.addEventListener(&quot;keydown&quot;, handleChange);
}, [input]);
return (
&lt;&gt;
&lt;div className=&quot;bg-gray-200 mx-auto my-10 w-3/4 p-10 shadow-sm shadow-gray-600 rounded-lg&quot;&gt;
&lt;form onSubmit={submit} className=&quot;mb-10&quot;&gt;
{englishQuestions.map((question) =&gt; {
index1 = index1 + 1;
return (
&lt;div
key={index1}
className={index1 === theValue.first ? &quot;&quot; : &quot;hidden&quot;}
&gt;
&lt;h3&gt;
&lt;span className={submitted ? &quot;text-gray-400&quot; : &quot;font-bold&quot;}&gt;
Q {index1}:
&lt;/span&gt;{&quot; &quot;}
{question.start}{&quot; &quot;}
&lt;span className=&quot;underline&quot;&gt;{question.theWord}&lt;/span&gt;{&quot; &quot;}
{question.end}
&lt;/h3&gt;
{question.options.map((item, index) =&gt; {
return (
&lt;div className=&quot;mb-3&quot; key={index}&gt;
&lt;label htmlFor=&quot;&quot;&gt;a: &lt;/label&gt;
&lt;input
id=&quot;a&quot;
type=&quot;radio&quot;
name={`englishQ${index1} : ${question.start} ${question.theWord} ${question.end}`}
value={item.a}
onChange={handleChange}
disabled={submitted ? true : false}
checked={keyCode === &quot;KeyA&quot; ? true : false}
/&gt;
&lt;label htmlFor=&quot;&quot;&gt; {item.a}&lt;/label&gt;
&lt;br /&gt;
&lt;label htmlFor=&quot;&quot;&gt;b: &lt;/label&gt;
&lt;input
id=&quot;b&quot;
type=&quot;radio&quot;
name={`englishQ${index1} : ${question.start} ${question.theWord} ${question.end}`}
value={item.b}
onChange={handleChange}
disabled={submitted ? true : false}
checked={keyCode === &quot;KeyB&quot; ? true : false}
/&gt;
&lt;label htmlFor=&quot;&quot;&gt; {item.b}&lt;/label&gt;
&lt;br /&gt;
&lt;label htmlFor=&quot;&quot;&gt;c: &lt;/label&gt;
&lt;input
id=&quot;c&quot;
type=&quot;radio&quot;
name={`englishQ${index1} : ${question.start} ${question.theWord} ${question.end}`}
value={item.c}
onChange={handleChange}
disabled={submitted ? true : false}
checked={keyCode === &quot;KeyC&quot; ? true : false}
/&gt;
&lt;label htmlFor=&quot;&quot;&gt; {item.c}&lt;/label&gt;
&lt;br /&gt;
&lt;label htmlFor=&quot;&quot;&gt;d: &lt;/label&gt;
&lt;input
id=&quot;d&quot;
type=&quot;radio&quot;
name={`englishQ${index1} : ${question.start} ${question.theWord} ${question.end}`}
value={item.d}
onChange={handleChange}
disabled={submitted ? true : false}
checked={keyCode === &quot;KeyD&quot; ? true : false}
/&gt;
&lt;label htmlFor=&quot;&quot;&gt; {item.d}&lt;/label&gt;
&lt;/div&gt;
);
})}
&lt;/div&gt;
);
})}
&lt;div className=&quot;flex justify-center&quot;&gt;
&lt;button
type=&quot;submit&quot;
name=&quot;submit&quot;
className=&quot;btnExam p-3 mx-auto cursor-pointer&quot;
&gt;
Submit
&lt;/button&gt;
&lt;/div&gt;
&lt;/form&gt;
&lt;/div&gt;
&lt;/&gt;
);
};
export default English;

答案1

得分: 1

你应该在输入框上使用onKeyDown属性,而不是onChange来处理按键操作。

例如:

<input onKeyDown={handleKeyPress} />

然后,你可以使用onClickonKeyDown来执行你想要的操作。

英文:

You should use the onKeyDown property on the input instead of the onChange to handle the key press.

E.g

&lt;input onKeyDown={handleKeyPress} /&gt;

...

 const handleKeyPress = (e) =&gt; { if (e.key === &#39;Backspace&#39;) ... }

Then you can use the onClick and onKeyDown to do whatever you want.

huangapple
  • 本文由 发表于 2023年2月14日 21:12:52
  • 转载请务必保留本文链接:https://go.coder-hub.com/75448366.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定