Задать вопрос
@1233211

Как в react выделить все чекбоксы?

Есть страница с чекбоксами, у которых name={'names'} и onChange={handleClickCheckbox}.

Вот так собираю данные с чекбоксов:

const [names, setNames] = useState([]);

const handleClickCheckbox = (e) => {
    const formData = new FormData(e.currentTarget.form);
    const names = formData.getAll('names');
    setNames(names);
}

Нужно создать ещё один чекбокс, при клике на который, нужно выделять все чекбоксы, у которых name='names'.
  • Вопрос задан
  • 514 просмотров
Подписаться 1 Простой Комментировать
Решения вопроса 1
0xD34F
@0xD34F Куратор тега React
Вот так собираю данные с чекбоксов:

const formData = new FormData(e.currentTarget.form);
const names = formData.getAll('names');
setNames(names);

Понятно. А react тогда зачем?
Если хотите продолжать в том же духе,...
...то обработчик события change для чекбокса, выставляющего/снимающего всё, будет выглядеть так:

const onAllSelectedChange = ({ target: { checked, form: { names } } }) => {
  names.forEach(n => n.checked = checked);
  setNames(checked ? Array.from(names, n => n.value) : []);
};

А для обычных чекбоксов обработчик можно переписать так (это чтобы изменение их состояния влияло на общий, которому надо будет имя задать, "allSelected"):

const onChange = ({ target: { form } }) => {
  const names = new FormData(form).getAll('names');
  const isAllSelected = names.length === form.names.length;
  const all = form.allSelected;
  all.checked = isAllSelected;
  all.indeterminate = !isAllSelected && !!names.length;
  setNames(names);
};

А если делать чуть менее дико, то

const Checkbox = forwardRef(({ label, ...props }, ref) =>
  <label>
    <input type="checkbox" ref={ref} {...props} />
    {label}
  </label>
);

function CheckboxGroup({
  items,
  label = item => item,
  selected,
  setSelected,
}) {
  const onChange = ({ target: { checked, dataset: { index } } }) =>
    setSelected(selected => checked
      ? [ ...selected, items[index] ]
      : selected.filter(n => n !== items[index])
    );

  const allSelectedRef = useRef();
  const onAllSelectedChange = ({ target: { checked } }) =>
    setSelected(checked ? [...items] : []);

  useEffect(() => {
    const isAllSelected = items.length === selected.length;
    allSelectedRef.current.checked = isAllSelected;
    allSelectedRef.current.indeterminate = !isAllSelected && !!selected.length;
  }, [ selected ]);

  return (
    <div className="checkbox-group">
      <Checkbox
        label="SELECT ALL"
        defaultChecked={false}
        onChange={onAllSelectedChange}
        ref={allSelectedRef}
      />
      {items.map((n, i) => (
        <Checkbox
          label={label(n)}
          data-index={i}
          checked={selected.includes(n)}
          onChange={onChange}
        />
      ))}
    </div>
  );
}

https://jsfiddle.net/kj9wet6L/
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
firedragon
@firedragon
Не джун-мидл-сеньор, а трус-балбес-бывалый.
Либо привязка, либо выбираете из дома по фильтру и черкаете их
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы