简体   繁体   English

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

[英]Unable to check/uncheck the checkbox

I am making a react application where checkboxes for jobtitles are populated from the dynamic data from api and it will be exactly like given snippet.我正在制作一个反应应用程序,其中职位的复选框是从 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>

Here the jobTitles data will be like,这里的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
   }
]

And I make the checkbox checked based on the value of "453":false like,而我做的复选框checked基础上的价值"453":false像,

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

And the checkboxes are checked here but when I try to uncheck the checkbox in onChange handler like,复选框在此处被选中,但是当我尝试取消选中onChange处理程序中的复选框时,例如,

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

The checkboxes are not unchecked.. If I console/inspect the input element then the checked atribute is not removed .复选框未被选中。如果我控制台/检查输入元素,则不会删除checked属性。

Additional Info: It is also not possible to check the checkbox which is in unchecked state.. So in common I couldn't make any change to checkbox..附加信息:也无法选中处于unchecked状态的复选框..所以通常我无法对复选框进行任何更改..

Could anybody please help me to achieve the solution and I am got stuck for too long with this as I am new to react..任何人都可以帮助我实现解决方案,我被困在这里太久了,因为我是新手。

Big thanks in advance.非常感谢提前。

Issue(s)问题)

Direct DOM mutation is an anti-pattern in react (it is outside react so react can't know to rerender).直接 DOM 突变是 react 中的一种反模式(它在 react 之外,所以 react 不知道要重新渲染)。

The handler also doesn't access the checked property of the onChange event.处理程序也不访问onChange事件的checked属性。

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

Solution解决方案

Use react state to maintain the checked status in component state.使用 react state 来维护组件状态下的选中状态。

Move the departments data into component state.departments数据移动到组件状态。

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

Move the handleJobTitle handler into the component.handleJobTitle处理程序移动到组件中。 I suggest using a curried function that accepts the sector id, department name, and the job id, you'll need these to "trace" the path to the correct nested object.我建议使用接受部门 id、部门名称和工作 id 的柯里化函数,您将需要这些来“跟踪”正确嵌套对象的路径。 You don't need to worry about getting the checked property from event.target as you can simply invert a checked value in state via the JobTitleID key value.您无需担心从event.target获取已checked属性,因为您可以通过JobTitleID键值简单地反转状态中的已checked值。

The idea here is to shallow copy any nested state, into new object references for react, that is being updated.这里的想法是将任何嵌套状态浅复制到正在更新的新对象引用中以进行反应。

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
    )
  );
};

Now simply attach the handleJobTitle to the input's onChange handler.现在只需将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]}
/>

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

You need to define an Id parameter in the input tag.您需要在输入标签中定义一个 Id 参数。

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

Then use that id to fetch the node and change its status然后使用该 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