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

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

Accesing form input element onChange

问题

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

以下是代码:

  1. import { useState, useEffect, useRef } from "react";
  2. import { useLocation } from "react-router-dom";
  3. import { englishQuestions } from "../questions/englishQ";
  4. const English = () => {
  5. // ... 省略了一些代码
  6. // 这是我无法访问`keydown`事件的`onChange`函数
  7. const handleChange = (e: any) => {
  8. // ... 省略了一些处理逻辑
  9. };
  10. const submit = (e: any) => {
  11. e.preventDefault();
  12. // ... 省略了一些提交逻辑
  13. };
  14. // 这里是事件监听器的调用
  15. useEffect(() => {
  16. document.body.addEventListener("keydown", handleChange);
  17. }, [input]);
  18. return (
  19. <>
  20. <div className="bg-gray-200 mx-auto my-10 w-3/4 p-10 shadow-sm shadow-gray-600 rounded-lg">
  21. <form onSubmit={submit} className="mb-10">
  22. {englishQuestions.map((question) => {
  23. // ... 省略了一些循环逻辑
  24. })}
  25. <div className="flex justify-center">
  26. <button
  27. type="submit"
  28. name="submit"
  29. className="btnExam p-3 mx-auto cursor-pointer"
  30. >
  31. Submit
  32. </button>
  33. </div>
  34. </form>
  35. </div>
  36. </>
  37. );
  38. };
  39. 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.

  1. import { useState, useEffect, useRef } from &quot;react&quot;;
  2. import { useLocation } from &quot;react-router-dom&quot;;
  3. import { englishQuestions } from &quot;../questions/englishQ&quot;;
  4. const English = () =&gt; {
  5. const theRef = useRef();
  6. const { state } = useLocation();
  7. const { user } = state;
  8. const [input, setInputs] = useState&lt;{ [key: string]: string }[]&gt;([]);
  9. const [answersSelected, setAnswersSelected] = useState({});
  10. const [selected, setSelected] = useState&lt;{ [key: string]: boolean }&gt;({});
  11. const [submitted, setSubmitted] = useState(false);
  12. const [keyCode, setKeyCode] = useState(&quot;&quot;);
  13. var index1 = 0;
  14. const answers = englishQuestions.map((items, index) =&gt; items.answer);
  15. //This is the `onChange` `function` from which I can&#39;t access `keydown` event
  16. const handleChange = (e: any) =&gt; {
  17. const numbers = /\d+/g;
  18. switch (e.code) {
  19. case &quot;keyA&quot;:
  20. setKeyCode(&quot;keyA&quot;);
  21. const { value, name } = e.target;
  22. const currentQuestionNumber = name.slice(name.indexOf(&quot;englishQ&quot;), 10);
  23. const currentQuestion = name.slice(name.indexOf(&quot;:&quot;) + 2);
  24. const currentArrayIndex = name.match(numbers)[0] - 1;
  25. if (answers[currentArrayIndex] === value) {
  26. setInputs([
  27. ...input,
  28. {
  29. questionNumber: currentQuestionNumber.trim(),
  30. question: currentQuestion,
  31. answer: value,
  32. status: &quot;correct&quot;,
  33. marks: &quot;2&quot;,
  34. },
  35. ]);
  36. setAnswersSelected({ ...answersSelected, [name]: value });
  37. } else {
  38. setInputs([
  39. ...input,
  40. {
  41. questionNumber: currentQuestionNumber.trim(),
  42. question: currentQuestion,
  43. answer: value,
  44. status: &quot;wrong&quot;,
  45. marks: &quot;0&quot;,
  46. },
  47. ]);
  48. setAnswersSelected({ ...answersSelected, [name]: value });
  49. }
  50. //detect if an answer was selected
  51. setSelected({ ...selected, [currentArrayIndex + 1]: true });
  52. //convert the answered object keys into an array
  53. const submittedKeys = Object.keys(selected);
  54. //check if all answers were selected
  55. const checkSelelction = submittedKeys.filter(
  56. (key, index) =&gt; selected[key] === true
  57. );
  58. if (checkSelelction.length + 1 &gt;= 10) {
  59. setAllSelected(true);
  60. } else {
  61. setAllSelected(false);
  62. }
  63. break;
  64. case &quot;keyB&quot;:
  65. setKeyCode(&quot;keyB&quot;);
  66. break;
  67. case &quot;keyC&quot;:
  68. setKeyCode(&quot;keyC&quot;);
  69. break;
  70. case &quot;keyD&quot;:
  71. setKeyCode(&quot;keyD&quot;);
  72. break;
  73. default:
  74. setKeyCode(&quot;&quot;);
  75. }
  76. setSelectedValue([...selectedValue, { theSelectedValue: e.target.value }]);
  77. localStorage.setItem(&quot;theSelectedValue&quot;, JSON.stringify(selectedValue));
  78. console.log(localStorage.getItem(&quot;theSelectedValue&quot;) as string);
  79. const { value, name } = e.target;
  80. const currentQuestionNumber = name.slice(name.indexOf(&quot;englishQ&quot;), 10);
  81. const currentQuestion = name.slice(name.indexOf(&quot;:&quot;) + 2);
  82. const currentArrayIndex = name.match(numbers)[0] - 1;
  83. if (answers[currentArrayIndex] === value) {
  84. setInputs([
  85. ...input,
  86. {
  87. questionNumber: currentQuestionNumber.trim(),
  88. question: currentQuestion,
  89. answer: value,
  90. status: &quot;correct&quot;,
  91. marks: &quot;2&quot;,
  92. },
  93. ]);
  94. setAnswersSelected({ ...answersSelected, [name]: value });
  95. } else {
  96. setInputs([
  97. ...input,
  98. {
  99. questionNumber: currentQuestionNumber.trim(),
  100. question: currentQuestion,
  101. answer: value,
  102. status: &quot;wrong&quot;,
  103. marks: &quot;0&quot;,
  104. },
  105. ]);
  106. setAnswersSelected({ ...answersSelected, [name]: value });
  107. }
  108. //detect if an answer was selected
  109. setSelected({ ...selected, [currentArrayIndex + 1]: true });
  110. //convert the answered object keys into an array
  111. const submittedKeys = Object.keys(selected);
  112. //check if all answers were selected
  113. const checkSelelction = submittedKeys.filter(
  114. (key, index) =&gt; selected[key] === true
  115. );
  116. if (checkSelelction.length + 1 &gt;= 10) {
  117. setAllSelected(true);
  118. } else {
  119. setAllSelected(false);
  120. }
  121. };
  122. const submit = (e: any) =&gt; {
  123. e.preventDefault();
  124. setSubmitted(true);
  125. localStorage.setItem(&quot;studentId&quot;, JSON.stringify(user.studentId));
  126. localStorage.setItem(&quot;englishSubmitted&quot;, &quot;true&quot;);
  127. localStorage.setItem(&quot;englishAnswers&quot;, JSON.stringify(input));
  128. };
  129. //Here is the call to the event listener
  130. useEffect(() =&gt; {
  131. document.body.addEventListener(&quot;keydown&quot;, handleChange);
  132. }, [input]);
  133. return (
  134. &lt;&gt;
  135. &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;
  136. &lt;form onSubmit={submit} className=&quot;mb-10&quot;&gt;
  137. {englishQuestions.map((question) =&gt; {
  138. index1 = index1 + 1;
  139. return (
  140. &lt;div
  141. key={index1}
  142. className={index1 === theValue.first ? &quot;&quot; : &quot;hidden&quot;}
  143. &gt;
  144. &lt;h3&gt;
  145. &lt;span className={submitted ? &quot;text-gray-400&quot; : &quot;font-bold&quot;}&gt;
  146. Q {index1}:
  147. &lt;/span&gt;{&quot; &quot;}
  148. {question.start}{&quot; &quot;}
  149. &lt;span className=&quot;underline&quot;&gt;{question.theWord}&lt;/span&gt;{&quot; &quot;}
  150. {question.end}
  151. &lt;/h3&gt;
  152. {question.options.map((item, index) =&gt; {
  153. return (
  154. &lt;div className=&quot;mb-3&quot; key={index}&gt;
  155. &lt;label htmlFor=&quot;&quot;&gt;a: &lt;/label&gt;
  156. &lt;input
  157. id=&quot;a&quot;
  158. type=&quot;radio&quot;
  159. name={`englishQ${index1} : ${question.start} ${question.theWord} ${question.end}`}
  160. value={item.a}
  161. onChange={handleChange}
  162. disabled={submitted ? true : false}
  163. checked={keyCode === &quot;KeyA&quot; ? true : false}
  164. /&gt;
  165. &lt;label htmlFor=&quot;&quot;&gt; {item.a}&lt;/label&gt;
  166. &lt;br /&gt;
  167. &lt;label htmlFor=&quot;&quot;&gt;b: &lt;/label&gt;
  168. &lt;input
  169. id=&quot;b&quot;
  170. type=&quot;radio&quot;
  171. name={`englishQ${index1} : ${question.start} ${question.theWord} ${question.end}`}
  172. value={item.b}
  173. onChange={handleChange}
  174. disabled={submitted ? true : false}
  175. checked={keyCode === &quot;KeyB&quot; ? true : false}
  176. /&gt;
  177. &lt;label htmlFor=&quot;&quot;&gt; {item.b}&lt;/label&gt;
  178. &lt;br /&gt;
  179. &lt;label htmlFor=&quot;&quot;&gt;c: &lt;/label&gt;
  180. &lt;input
  181. id=&quot;c&quot;
  182. type=&quot;radio&quot;
  183. name={`englishQ${index1} : ${question.start} ${question.theWord} ${question.end}`}
  184. value={item.c}
  185. onChange={handleChange}
  186. disabled={submitted ? true : false}
  187. checked={keyCode === &quot;KeyC&quot; ? true : false}
  188. /&gt;
  189. &lt;label htmlFor=&quot;&quot;&gt; {item.c}&lt;/label&gt;
  190. &lt;br /&gt;
  191. &lt;label htmlFor=&quot;&quot;&gt;d: &lt;/label&gt;
  192. &lt;input
  193. id=&quot;d&quot;
  194. type=&quot;radio&quot;
  195. name={`englishQ${index1} : ${question.start} ${question.theWord} ${question.end}`}
  196. value={item.d}
  197. onChange={handleChange}
  198. disabled={submitted ? true : false}
  199. checked={keyCode === &quot;KeyD&quot; ? true : false}
  200. /&gt;
  201. &lt;label htmlFor=&quot;&quot;&gt; {item.d}&lt;/label&gt;
  202. &lt;/div&gt;
  203. );
  204. })}
  205. &lt;/div&gt;
  206. );
  207. })}
  208. &lt;div className=&quot;flex justify-center&quot;&gt;
  209. &lt;button
  210. type=&quot;submit&quot;
  211. name=&quot;submit&quot;
  212. className=&quot;btnExam p-3 mx-auto cursor-pointer&quot;
  213. &gt;
  214. Submit
  215. &lt;/button&gt;
  216. &lt;/div&gt;
  217. &lt;/form&gt;
  218. &lt;/div&gt;
  219. &lt;/&gt;
  220. );
  221. };
  222. export default English;

答案1

得分: 1

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

例如:

  1. <input onKeyDown={handleKeyPress} />

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

英文:

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

E.g

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

...

  1. 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:

确定