React中无法获取选中任务按钮的值并展示到侧边导航问题求助
问题分析与解决方案
我一眼就看出问题所在啦——你现在把JSX按钮元素直接存在了tasks数组里,而且在创建按钮的时候,onClick事件里引用的taskdom.value是点击任务按钮时输入框的当前值(早就被清空了),不是你创建这个任务时输入的文本!
核心问题拆解:
- 当你点击
+按钮添加任务时,你先创建了一个按钮JSX,其中的onClick会在未来点击任务按钮时执行,这时候去读taskdom.value,输入框已经被你清空成空字符串了,所以selectedTask自然是空的。 - 另外,React里不建议直接操作DOM(比如
document.getElementById),也不要把JSX元素存在state里,应该存数据,再用数据渲染UI。
修复后的完整代码:
import './index.css'; import React, {useState, useRef} from 'react'; function App() { return ( <div> <TodoListItem /> </div> ); } const TodoListItem = (props) => { // 现在存储任务文本字符串,而不是JSX元素 const [tasks, setTasks] = useState([]); const [toggle, setToggle]= useState(true); const [grid, setGrid]= useState(''); const [selectedTask, setSelectedTask]= useState(''); // 用useRef代替getElementById,更符合React规范 const taskInputRef = useRef(null); const TodoItemDetails = () => { setToggle(false) setGrid("grid grid-cols-2") } const onFormSubmit = e => { e.preventDefault(); // 获取输入框的值 const newTaskText = taskInputRef.current.value.trim(); if (!newTaskText) return; // 空任务不添加 // 添加新任务文本到数组 setTasks(prevTasks => [...prevTasks, newTaskText]); // 清空输入框 taskInputRef.current.value = ""; } return ( <div className="bg-gray-100 items-center justify-center min-h-screen min-w-screen p-4"> <div className={grid}> {/* grid one */} <div> <form onSubmit={onFormSubmit} className="bg-white rounded py-4 px-2 my-4 h-16 shadow-sm"> {/* 使用ref绑定输入框 */} <input ref={taskInputRef} className="w-[92%] h-full float-left focus:outline-none placeholder-blue-500 ml-2 py-1 focus:placeholder-black" type="text" placeholder="Add a task" /> {/* 提交按钮可以直接用form的onSubmit,不用在按钮里写逻辑 */} <button type="submit" className="text-blue-500 float-right text-2xl -translate-y-0.5 -translate-x-1">+</button> </form> {/* 用任务文本数据渲染按钮,每个按钮携带自己的文本 */} {tasks.map((taskText, index) => ( <button key={index} // 列表元素需要唯一key onClick={() => { TodoItemDetails(); // 直接用当前任务的文本设置selectedTask setSelectedTask(taskText); }} className="bg-white w-full hover:bg-gray-200 p-4 my-1 rounded shadow-sm text-left" > {taskText} </button> ))} </div> {/* grid two: side nav bar */} <div hidden={toggle}> <button onClick={() => { setToggle(true) setGrid("") }}>{selectedTask}</button> </div> </div> </div> ); } export default App;
关键修复点:
- 把
tasks改为存储文本字符串:这样我们始终持有每个任务的真实内容,而不是依赖DOM的当前状态。 - 用
useRef获取输入框:React推荐用ref来访问DOM元素,比document.getElementById更安全,尤其是在组件重新渲染时。 - 拆分逻辑到
onFormSubmit:把添加任务的逻辑统一放在表单提交事件里,代码更清晰,也避免了按钮点击和表单提交的重复逻辑。 - 动态渲染任务按钮:遍历
tasks数组,为每个任务文本生成按钮,点击时直接用当前任务的文本设置selectedTask,再也不会为空啦! - 替换
class为className:React里DOM元素的类名属性是className,不是class(避免和JS的class关键字冲突)。
内容的提问来源于stack exchange,提问作者Ushira Dineth
相关产品推荐
相关产品推荐

