React待办列表受控输入框按回车清空异常仅显示首字符问题
问题根源
- 输入框的
onKeyDown事件未做按键过滤,任意按键按下都会直接执行setTodoInput("")清空输入值,之后才触发onChange更新为当前输入的单个字符,最终表现为输入框永远只显示最后输入的单个字符。 - 回车键添加任务的逻辑重复冗余,App组件和InputArea组件内都写了添加逻辑,会导致一次回车添加两次相同任务。
- 未阻止回车键的默认行为,可能触发浏览器默认的表单提交操作,引发页面异常。
修复方案
直接统一在InputArea组件内处理回车逻辑,复用已有的onAdd方法即可,无需在App层单独处理回车事件,具体修改如下:
修复后的InputArea组件代码
import React, { useState } from "react"; function InputArea(props) { const [todoInput, setTodoInput] = useState(""); function handleChange(event) { const newInput = event.target.value; setTodoInput(newInput); } return ( <div className="form"> <input onKeyDown={(event) => { // 仅处理回车键事件 if (event.key === "Enter") { event.preventDefault(); // 阻止浏览器默认回车行为 props.onAdd(todoInput); // 复用已封装的添加逻辑 setTodoInput(""); // 确认是回车键后再清空输入框 } }} onChange={handleChange} type="text" value={todoInput} /> <button onClick={() => { props.onAdd(todoInput); setTodoInput(""); }} > <span>Add</span> </button> </div> ); } export default InputArea;
修复后的App组件代码
删掉冗余的handleKeyPress逻辑和对应的传参即可:
import React, { useState } from "react"; import InputArea from "./InputArea"; import ToDoTask from "./ToDoTask"; function App() { const [todoTasks, setTodoTasks] = useState([]); function addTask(todoInput) { setTodoTasks((prevTodoTasks) => { return [...prevTodoTasks, todoInput]; }); } function deleteTodoTask(id) { setTodoTasks((prevTodoTasks) => { return prevTodoTasks.filter((task, i) => { return i !== id; }); }); } return ( <div className="container"> <div className="heading"> <h1>To-Do List</h1> </div> <div className="form"> <InputArea onAdd={addTask} /> </div> <div> <ul> {todoTasks.map((todoTasks, i) => ( <ToDoTask key={i} id={i} text={todoTasks} onChecked={deleteTodoTask} /> ))} </ul> </div> </div> ); } export default App;
内容的提问来源于stack exchange,提问作者N.O
相关产品推荐
相关产品推荐

