1

My purpouse here is to create a group of checboxes. "Search everywhere" is default checked, if you check something else "Search everywhere" automatically unchecked, you can check as many different checkboxes as you want, until you check "search everywhere" again, if you do that all other checkboxes will unchecked. I want to create it in function component with Hooks in React. View: Image how it looks in browser

Everything is ready, but I stuck a little bit with toggle between one checkbox and group of checkboxes. I've tried useState and useEffect to controll useState callback. Thanks for help.

const ButtonCategory = (props) => {
  const [state, setState] = useState({
    normalCheckbox: false,
    specialCheckbox: true
  });
  const { id, name, special, products } = props;

  const toggleOthers = () => {
    if (state.specialCheckbox) {
      setState({
        ...state,
        normalCheckbox: false // ofc its bad
      });
    } else if (state.normalCheckbox) {
      setState({
        ...state,
        specialCheckbox: false // ofc its bad
      });
    }
  };

  const toggleNormal = () => {
    setState({
      ...state,
      normalCheckbox: !state.normalCheckbox
    });
  };

  const toggleSpecial = () => {
    setState({
      ...state,
      specialCheckbox: !state.specialCheckbox
    });
  };

  useEffect(() => {
    toggleOthers();
  }, [state.specialCheckbox, state.normalCheckbox]);

  return (
    <>
      <Label>
        <StyledInput
          type="checkbox"
          id={id}
          checked={special ? state.specialCheckbox : state.normalCheckbox}
          onChange={special ? () => toggleSpecial() : () => toggleNormal()}
          onClick={(e) => {
            /* do something */
          }}
        />{" "}
        <div>
          {" "}
          {name} {special ? null : `(${products})`}
        </div>
      </Label>
    </>
  );
};
mekwall
  • 28,614
  • 6
  • 75
  • 77
4sp3ll
  • 13
  • 6

2 Answers2

0

I believe you want something like this:

import React, { useState } from "react";

export const Checkboxes = () => {
  const [checkedIds, setCheckedIds] = useState(new Set(["everywhere"]));

  const handleCheck = ({ id, checked }) => {
    if (checked) {
      if (id === "everywhere") {
        checkedIds.clear();
      } else {
        checkedIds.delete("everywhere");
      }
      checkedIds.add(id);
    } else {
      checkedIds.delete(id);
    }
    setCheckedIds(new Set(checkedIds));
  };

  return (
    <form>
      <label>
        <input
          id="everywhere"
          type="checkbox"
          checked={checkedIds.has("everywhere")}
          onChange={(e) => handleCheck(e.target)}
        />{" "}
        Search everywhere
      </label>

      <label>
        <input
          id="option-1"
          type="checkbox"
          checked={checkedIds.has("option-1")}
          onChange={(e) => handleCheck(e.target)}
        />{" "}
        Option 1
      </label>

      <label>
        <input
          id="option-2"
          type="checkbox"
          checked={checkedIds.has("option-2")}
          onChange={(e) => handleCheck(e.target)}
        />{" "}
        Option 2
      </label>
    </form>
  );
};

Test case at codesandbox.io

mekwall
  • 28,614
  • 6
  • 75
  • 77
0

May be this could be helpful

import React from "react";
import "./style.css";

export const App = () => {
  const _checkboxes = [
    {
      id: "id1",
      name: "111",
      value: "111",
      label: "111",
      checked: true
    },
    {
      id: "id2",
      name: "222",
      value: "222",
      label: "222",
      checked: false
    },
    {
      id: "id3",
      name: "333",
      value: "333",
      label: "333",
      checked: false
    }
  ];

  const [checkboxes, setCheckboxes] = React.useState(_checkboxes);

  const handleChange = id => e => {
    setCheckboxes(checkboxes => {
      const firstId = "id1";
      const temp = checkboxes.map(c => {
        if (firstId === id) {
          c.checked = c.id === firstId ? !c.checked : false;
        } else {
          if (c.id === id) {
            c.checked = !c.checked;
          } else {
            if (c.id === firstId) {
              c.checked = false;
            }
          }
        }

        return c;
      });

      return [...temp];
    });
  };

  return (
    <div>
      {checkboxes.map(checkbox => (
        <div key={checkbox.id}>
          <input
            type="checkbox"
            onChange={handleChange(checkbox.id)}
            value={checkbox.value}
            name={checkbox.name}
            id={checkbox.id}
            checked={checkbox.checked}
          />
          <label htmlFor={checkbox.id}>{checkbox.label}</label>
        </div>
      ))}
    </div>
  );
};

https://stackblitz.com/edit/react-rtxxfp?file=src%2FApp.js

Lashan Fernando
  • 1,187
  • 1
  • 7
  • 21