无法选中/取消选中复选框 [英] Unable to check/uncheck the checkbox

查看:194
本文介绍了无法选中/取消选中复选框的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在制作一个React应用程序,其中使用来自api的动态数据填充求职者的复选框,这就像给定的代码段一样.

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.

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
   }
]

然后我根据"453":false的值来选中checked复选框,

And I make the checkbox checked based on the value of "453":false like,

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

这里选中了复选框,但是当我尝试取消选中onChange处理程序之类的复选框时,

And the checkboxes are checked here but when I try to uncheck the checkbox in onChange handler like,

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

未取消选中复选框..如果我对输入元素进行控制台/检查,则checked属性没有未删除.

The checkboxes are not unchecked.. If I console/inspect the input element then the checked atribute is not removed.

其他信息:也无法选中处于unchecked状态的复选框..因此,通常我无法对复选框进行任何更改..

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..

有人可以帮助我实现解决方案吗?由于我是新来的反应者,我为此而陷于太久了.

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..

预先表示感谢.

推荐答案

问题

直接DOM突变是反应中的反模式(它是外部反应,因此反应不知道要重新呈现).

Issue(s)

Direct DOM mutation is an anti-pattern in react (it is outside react so react can't know to rerender).

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

The handler also doesn't access the checked property of the onChange event.

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

解决方案

使用反应状态将检查后的状态保持在组件状态.

Solution

Use react state to maintain the checked status in component state.

departments数据移动到组件状态.

Move the departments data into component state.

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

handleJobTitle处理程序移动到组件中.我建议使用一个接受部门ID,部门名称和工作ID的咖喱函数,您将需要使用这些函数来跟踪"代码.正确的嵌套对象的路径.您不必担心从event.target获取checked属性,因为您可以通过JobTitleID键值简单地将checked值转换为状态.

Move the handleJobTitle handler into the component. 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. 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.

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

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

现在,只需将handleJobTitle附加到输入的onChange处理程序即可.

Now simply attach the handleJobTitle to the input's onChange handler.

<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]}
/>

这篇关于无法选中/取消选中复选框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆