繁体   English   中英

无法选中/取消选中复选框

[英]Unable to check/uncheck the checkbox

我正在制作一个反应应用程序,其中职位的复选框是从 api 的动态数据填充的,它将与给定的片段完全一样。

 const departments = [ { "sectorId":29, "sectorName":"Building Materials Mfg. & Distribution", "departments":[ { "deptName":"Manufacturing", "jobTitles":[ { "453":false, "JobTitleID":453, "DepartmentID":101, "JobName":"Consultant", "Deleted":false, "SortOrder":5 }, { "323":true, "JobTitleID":323, "DepartmentID":101, "JobName":"Quality Control", "Deleted":false, "SortOrder":1 } ] }, { "deptName":"Warehouse", "jobTitles":[ { "326":false, "JobTitleID":326, "DepartmentID":98, "JobName":"Warehouse Supervisor", "Deleted":false, "SortOrder":1 } ] }, { "deptName":"Administration", "jobTitles":[ { "384":true, "JobTitleID":384, "DepartmentID":115, "JobName":"Controller", "Deleted":false, "SortOrder":1 } ] } ] } ] const handleJobTitle = (event, job) => { const { checked } = event.target; if (checked) { document.getElementById(job.JobTitleID).checked = true; } else { document.getElementById(job.JobTitleID).checked = false; } console.log(document.getElementById(job.JobTitleID)); }; const App = () => ( <div> {departments && departments.map((levelOne, i) => ( <div key={i} > <p> {levelOne.sectorName} </p> {levelOne.departments.map((levelTwo, j) => ( <div key={j}> <p > {" "} {levelTwo.deptName}{" "} </p> {levelTwo.jobTitles.map((job, l) => ( <div key={l} > <input type="checkbox" id={job.JobTitleID} onChange={(e) => {handleJobTitle(e, job)}} name={job.JobName} checked={job[job.JobTitleID]}/> <span>{job.JobName}</span> </div> ))} </div> ))} </div> ))} </div> ) // Render it ReactDOM.render( <App />, document.getElementById("root") );
 <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script> <div id="root"></div>

这里的jobTitles数据将是这样的,

"jobTitles":[
   {
      "453":false,
      "JobTitleID":453,
      "DepartmentID":101,
      "JobName":"Consultant",
      "Deleted":false,
      "SortOrder":5
   },
   {
      "323":true,
      "JobTitleID":323,
      "DepartmentID":101,
      "JobName":"Quality Control",
      "Deleted":false,
      "SortOrder":1
   }
]

而我做的复选框checked基础上的价值"453":false像,

<input type="checkbox" ...... checked={job[job.JobTitleID]}/>

复选框在此处被选中,但是当我尝试取消选中onChange处理程序中的复选框时,例如,

const handleJobTitle = (event, job) => { 
 document.getElementById(job.JobTitleID).checked = false;
}

复选框未被选中。如果我控制台/检查输入元素,则不会删除checked属性。

附加信息:也无法选中处于unchecked状态的复选框..所以通常我无法对复选框进行任何更改..

任何人都可以帮助我实现解决方案,我被困在这里太久了,因为我是新手。

非常感谢提前。

问题)

直接 DOM 突变是 react 中的一种反模式(它在 react 之外,所以 react 不知道要重新渲染)。

处理程序也不访问onChange事件的checked属性。

const { checked } = event; // <-- should be event.target

解决方案

使用 react state 来维护组件状态下的选中状态。

departments数据移动到组件状态。

const [departments, setDepartments] = useState(departmentsData);

handleJobTitle处理程序移动到组件中。 我建议使用接受部门 id、部门名称和工作 id 的柯里化函数,您将需要这些来“跟踪”正确嵌套对象的路径。 您无需担心从event.target获取已checked属性,因为您可以通过JobTitleID键值简单地反转状态中的已checked值。

这里的想法是将任何嵌套状态浅复制到正在更新的新对象引用中以进行反应。

const handleJobTitle = (sectorId, deptName, JobTitleID) => () => {
  setDepartments((data) =>
    data.map((sector) =>
      sector.sectorId === sectorId
        ? {
            ...sector,
            departments: sector.departments.map((dept) =>
              dept.deptName === deptName
                ? {
                    ...dept,
                    jobTitles: dept.jobTitles.map((job) =>
                      job.JobTitleID === JobTitleID
                        ? {
                            ...job,
                            [JobTitleID]: !job[JobTitleID]
                          }
                        : job
                    )
                  }
                : dept
            )
          }
        : sector
    )
  );
};

现在只需将handleJobTitle附加到输入的onChange处理程序。

<input
  type="checkbox"
  id={job.JobTitleID}
  onChange={handleJobTitle( // <-- pass the required values
    levelOne.sectorId,
    levelTwo.deptName,
    job.JobTitleID
  )}
  name={job.JobName}
  checked={job[job.JobTitleID]}
/>

编辑无法取消选中的复选框

您需要在输入标签中定义一个 Id 参数。

<input type="checkbox" id="JobTitleCheckBox" ...... checked={job[job.JobTitleID]}/>

然后使用该 id 获取节点并更改其状态

const handleJobTitle = (event, job) => {
   document.getElementById(job.JobTitleID).checked = false;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM