You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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;

关键修复点:

  1. 把tasks改为存储文本字符串:这样我们始终持有每个任务的真实内容,而不是依赖DOM的当前状态。
  2. 用useRef获取输入框:React推荐用ref来访问DOM元素,比document.getElementById更安全,尤其是在组件重新渲染时。
  3. 拆分逻辑到onFormSubmit:把添加任务的逻辑统一放在表单提交事件里,代码更清晰,也避免了按钮点击和表单提交的重复逻辑。
  4. 动态渲染任务按钮:遍历tasks数组,为每个任务文本生成按钮,点击时直接用当前任务的文本设置selectedTask,再也不会为空啦!
  5. 替换class为className:React里DOM元素的类名属性是className,不是class(避免和JS的class关键字冲突)。

内容的提问来源于stack exchange,提问作者Ushira Dineth

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 15:37:45