Невозможно установить / снять флажок

Я создаю приложение для реагирования, в котором флажки для заголовков заданий заполняются из динамических данных из 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 .. В общем, я не мог изменить этот флажок ..

Может ли кто-нибудь помочь мне найти решение, и я слишком долго застрял в этом, поскольку я новичок, чтобы отреагировать ...

Заранее большое спасибо.


person Undefined    schedule 30.10.2020    source источник
comment
Проблема с прямым изменением / изменением DOM заключается в том, что это происходит вне экосистемы реакции; React не знает, что нужно выполнить повторную визуализацию, чтобы обновить пользовательский интерфейс. Значение job[job.JobTitleID] не находится в состоянии реакции / свойствах и никогда не обновляется.   -  person Drew Reese    schedule 30.10.2020
comment
@DrewReese, Спасибо за замечание .. Не могли бы вы помочь мне добиться результата с помощью состояния? Мне предоставлены данные из api, как указано выше, и я заполнил соответствующий флажок. Поэтому единственная проблема заключается в том, чтобы установить / снять флажок, флажок не работает, и я могу понять ваше объяснение. Не могли бы вы предоставить мне правильное решение, используя state/props в этом случае пожалуйста..   -  person Undefined    schedule 30.10.2020
comment
@DrewReese, Бро, не могли бы вы помочь мне в вопросе, в котором я взял решение из вашего предыдущего ответа, но оно не работает .. Вопрос здесь: stackoverflow.com/q/64967082/13270726   -  person Undefined    schedule 23.11.2020
comment
@DrewReese, Ничего страшного, если вы поможете утром в свое время .. Я действительно верю, что вы будете тем человеком, который ответит на вопрос о том, как сделать прокрутку к соответствующему элементу fieldset при щелчке по выбранному элементу.   -  person Undefined    schedule 23.11.2020
comment
@DrewReese, У вас была возможность помочь мне в данном вопросе? Жду вашего решения со вчерашнего дня .. Пожалуйста, помогите мне, Риз ..   -  person Undefined    schedule 24.11.2020


Ответы (2)


Проблемы)

Прямая мутация DOM - это антипаттерн в реакции (это внешняя реакция, поэтому react не может знать, что нужно выполнить повторную визуализацию).

Обработчик также не имеет доступа к свойству checked события onChange.

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

Решение

Используйте состояние реакции, чтобы поддерживать проверенный статус в состоянии компонента.

Переместите данные departments в состояние компонента.

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

Переместите обработчик handleJobTitle в компонент. Я предлагаю использовать каррированную функцию, которая принимает идентификатор сектора, название отдела и идентификатор задания, они понадобятся вам для отслеживания пути к правильному вложенному объекту. Вам не нужно беспокоиться о получении свойства checked из event.target, поскольку вы можете просто инвертировать значение checked в состоянии с помощью значения ключа JobTitleID.

Идея здесь состоит в том, чтобы неглубоко скопировать любое вложенное состояние в новые ссылки на объекты для реагирования, которые обновляются.

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

 Изменить невозможно-снять-отметку-флажок

person Drew Reese    schedule 30.10.2020
comment
Спасибо за вашу быструю помощь .. И я очень ценю это .. Разве нельзя делать что-то без изменения исходных данных? Потому что вы удалили идентификатор должности и поместили туда отметку с логическими значениями ... То есть невозможно без изменения этой части? - person Undefined; 30.10.2020
comment
@Undefined Это было для быстрой демонстрации ... вы могли обрабатывать свои данные, когда компонент монтируется, и вычислять проверенное свойство, и нет необходимости удалять эти нечетные ключи-значения (в новую ссылку на объект / массив OFC ). Для обработчика лучше иметь согласованный ключ / свойство для проверки. Позвольте мне поиграть с динамическими клавишами, вы должны были увидеть, что я могу заставить работать. - person Drew Reese; 30.10.2020
comment
@Undefined Обновленное решение, позволяющее использовать динамические ключи и не требовать изменений / дополнений в исходных данных. - person Drew Reese; 30.10.2020
comment
Вы великолепны, и спасибо за ваши изменения по моей просьбе .. Я учусь у вас многому, и я еще раз благодарю вас за помощь .. - person Undefined; 30.10.2020

Вам необходимо определить параметр Id во входном теге.

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

Затем используйте этот идентификатор, чтобы получить узел и изменить его статус.

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