点击Save按钮后输入框占位符未清空且团队信息无法加载的问题
问题修复方案
问题根源
- 输入框未绑定状态值:仅用
placeholder显示团队信息,未将输入框value与状态绑定。添加团队后输入内容残留,覆盖placeholder导致无法重置;点击其他团队时,输入框内容不会同步更新为选中团队的信息。 - 选中团队未同步表单状态:点击折叠面板仅更新了
teamName,但未将表单数据同步为选中团队的信息,导致输入框无变化。 - Description输入框禁用状态固定:该输入框硬编码
disabled属性,无法在添加/编辑模式下启用。
修复步骤与代码修改
1. 调整Home组件:提升表单状态到父组件
将表单状态updatedTeamDetails移至Home组件,方便选中团队时同步更新,同时统一管理模式切换逻辑:
// Home.tsx import { Helmet } from "react-helmet"; import { useState } from "react"; import TeamManagement from "../components/TeamManagement"; import TeamDetails from "../components/TeamDetails"; export default function Home() { const [teamName, setTeamName] = useState(""); const [isAddTeamMode, setIsAddTeamMode] = useState(true); const [teams, setTeams] = useState([ { id: 1, name: "FINANCE", teamLead: "John Doe", description: "finance department description", status: "active" }, { id: 2, name: "NUTRITION", teamLead: "Mike Green", description: "Nutrition department description", status: "active" }, { id: 3, name: "PROCUREMENT", teamLead: "Dave Brown", description: "Procurement department description", status: "active" }, { id: 4, name: "EQUIPMENT SERVICES", teamLead: "Jim Jones", description: "Equipment Services description", status: "active" }, { id: 5, name: "SITE BASED OPERATIONS", teamLead: "Steve Smith", description: "Site based operations description", status: "active" }, ]); // 提升表单状态到父组件,统一管理 const [updatedTeamDetails, setUpdatedTeamDetails] = useState({ name: "", teamLead: "", description: "", status: "", }); function handleTeamDetails(teamName: string) { setTeamName(teamName); // 选中团队时同步更新表单数据 const selectedTeam = teams.find(team => team.name === teamName); if (selectedTeam) { setUpdatedTeamDetails({ name: selectedTeam.name, teamLead: selectedTeam.teamLead, description: selectedTeam.description, status: selectedTeam.status, }); } } function addTeam() { setIsAddTeamMode(false); setTeamName(""); // 清空表单,准备添加新团队 setUpdatedTeamDetails({ name: "", teamLead: "", description: "", status: "" }); } function saveTeam() { const newTeamId = teams.length + 1; const newTeam = { id: newTeamId, ...updatedTeamDetails }; setTeams([...teams, newTeam]); setIsAddTeamMode(true); setTeamName(""); setUpdatedTeamDetails({ name: "", teamLead: "", description: "", status: "" }); } function cancelSave() { setIsAddTeamMode(true); setTeamName(""); setUpdatedTeamDetails({ name: "", teamLead: "", description: "", status: "" }); } return ( <div> <Helmet> <title>Home Page</title> </Helmet> <h2>Hello World!</h2> <div style={{ display: "flex" }}> <TeamManagement setTeamDetails={handleTeamDetails} teams={teams} addTeam={addTeam} /> <TeamDetails teamName={teamName} teams={teams} isAddTeamMode={isAddTeamMode} updatedTeamDetails={updatedTeamDetails} setUpdatedTeamDetails={setUpdatedTeamDetails} cancelSave={cancelSave} onSaveTeam={saveTeam} /> </div> </div> ); }
2. 简化TeamManagement组件
移除冗余逻辑,确保点击折叠面板时正确传递团队名称:
// TeamManagement.tsx /* eslint-disable react/prop-types */ import { Accordion } from "react-bootstrap"; import "../css/app.css"; interface Props { setTeamDetails: (teamName: string) => void; teams: Array<{ id: number; name: string }>; addTeam: () => void; } export default function TeamManagement(props: Props) { return ( <div className="team-management"> <div> <h4>Team Management</h4> </div> <div> <button onClick={props.addTeam}>Add Team</button> </div> <div> {props.teams.map((team) => ( <Accordion key={team.id} defaultActiveKey="0"> <Accordion.Item eventKey="0" onClick={() => props.setTeamDetails(team.name)}> <Accordion.Header>{team.name}</Accordion.Header> </Accordion.Item> </Accordion> ))} </div> </div> ); }
3. 重构TeamDetails组件:绑定状态与输入框
修改输入框逻辑,根据模式切换显示数据,统一禁用状态:
// TeamDetails.tsx /* eslint-disable react/prop-types */ import "../css/app.css"; interface Props { teamName: string; teams: Array<{ id: number; name: string; teamLead: string; description: string; status: string }>; isAddTeamMode: boolean; updatedTeamDetails: { name: string; teamLead: string; description: string; status: string }; setUpdatedTeamDetails: (details: { name: string; teamLead: string; description: string; status: string }) => void; cancelSave: () => void; onSaveTeam: () => void; } export default function TeamDetails(props: Props) { const selectedTeam = props.teams.find(team => team.name === props.teamName); return ( <div className="team-details"> <div> <h4>Team Details: {props.teamName || "New Team"}</h4> </div> <div style={{ display: "flex", flexDirection: "column" }}> <label htmlFor="teamNameInput">Team Name:</label> <input type="text" id="teamNameInput" // 查看模式显示选中团队数据,添加模式显示表单输入数据 value={props.isAddTeamMode ? (selectedTeam?.name || "") : props.updatedTeamDetails.name} disabled={props.isAddTeamMode} placeholder={props.isAddTeamMode ? "" : "Enter team name"} onChange={(e) => props.setUpdatedTeamDetails({ ...props.updatedTeamDetails, name: e.target.value })} /> <label htmlFor="teamLeadInput">Team Lead:</label> <input type="text" id="teamLeadInput" value={props.isAddTeamMode ? (selectedTeam?.teamLead || "") : props.updatedTeamDetails.teamLead} disabled={props.isAddTeamMode} placeholder={props.isAddTeamMode ? "" : "Enter team lead"} onChange={(e) => props.setUpdatedTeamDetails({ ...props.updatedTeamDetails, teamLead: e.target.value })} /> <label htmlFor="descriptionInput">Description:</label> <input type="text" id="descriptionInput" value={props.isAddTeamMode ? (selectedTeam?.description || "") : props.updatedTeamDetails.description} disabled={props.isAddTeamMode} placeholder={props.isAddTeamMode ? "" : "Enter description"} onChange={(e) => props.setUpdatedTeamDetails({ ...props.updatedTeamDetails, description: e.target.value })} /> <label htmlFor="statusInput">Status:</label> <input type="text" id="statusInput" value={props.isAddTeamMode ? (selectedTeam?.status || "") : props.updatedTeamDetails.status} disabled={props.isAddTeamMode} placeholder={props.isAddTeamMode ? "" : "Enter status"} onChange={(e) => props.setUpdatedTeamDetails({ ...props.updatedTeamDetails, status: e.target.value })} /> <label htmlFor="teamMembersSelect">Team Members:</label> <select id="teamMembersSelect" disabled={props.isAddTeamMode}> <option value="member1">Member 1</option> <option value="member2">Member 2</option> <option value="member3">Member 3</option> </select> </div> <div style={{ display: "flex", margin: "10px", justifyContent: "space-between" }}> <div> <button onClick={(e) => { e.stopPropagation(); props.onSaveTeam(); }} disabled={props.isAddTeamMode} > Save </button> </div> <div> <button onClick={props.cancelSave} disabled={props.isAddTeamMode}> Cancel </button> </div> </div> </div> ); }
内容的提问来源于stack exchange,提问作者mattangel
相关产品推荐
相关产品推荐

