1

I need to control all checkboxes using hooks in React

Code for parent

const Filter = () => {

  const [isChecked, setIsChecked] = useState({
    all: false,
    without: false,
    one: false,
    two: false,
    three: false,
  })

  const handleChange = ({ target : { name, checked } }) => {
    setIsChecked({ 
      ...isChecked, 
      [name]: checked 
    })
  }

  const checkboxes = [
    {
      key: "all",
      name: "all",
      htmlFor: "all",
      label: "Все"
    },
    {
      key: "without",
      name: "without",
      htmlFor: "without",
      label: "Без пересадок"
    },
    {
      key: "one",
      name: "one",
      htmlFor: "one",
      label: "1 пересадка"
    },
    {
      key: "two",
      name: "two",
      htmlFor: "two",
      label: "2 пересадки"
    },
    {
      key: "three",
      name: "three",
      htmlFor: "three",
      label: "3 пересадки"
    },
  ];
  return (
    <div className="content__filter">
      <div className="content__filter__name">
        Количество пересадок
      </div>
      <div className="content__filter__list">
        <ul>
          {checkboxes.map(item => (
            <ListItem 
              key={item.key}
              name={item.name} 
              htmlFor={item.htmlFor} 
              label={item.label}
              checked={isChecked[item.name]}
              onChange={handleChange}
            />
          ))}
        </ul>
      </div>
    </div>
  );
};

export default Filter;

Code for children

const ListItem = ({ type = "checkbox", name, htmlFor, label, onChange, checked }) => {
  console.log(checked)
  return (
    <li>
      <input type={type} name={name} checked={checked} onChange={onChange}/>
      <label htmlFor={htmlFor}>{label}</label>
    </li>
  )
};

export default ListItem;

Checkboxes don't react at all. I mean if I click, nothing happens. I get false property all the time in the children and it can't be switched. Also it doesn't work if I set isChecked as an empty object (like in this example https://codesandbox.io/s/react-hooks-usestate-xzvq5?file=/src/index.js:380-382) What am I doing wrong? Any help appreciated

P.s. CSS for checkbox

li {
  display: flex;
  align-items: center;
  height: 40px;

  &:hover {
    background: #F1FCFF;
    cursor: pointer;
  }

  input {
    display: none;
  }

  label {
    font-family: 'Open Sans';
    font-weight: 400;
    font-size: 13px;
    color: #4A4A4A;
    cursor: pointer;
  }

  input + label {
    display: inline-flex;
    align-items: center;
    user-select: none;
  }

  input + label::before {
    content: '';
    display: inline-block;
    width: 20px;
    height: 20px;
    flex-shrink: 0;
    flex-grow: 0;
    border: 1px solid #9ABBCE;
    border-radius: 2px;
    margin-right: 10px;
    background-repeat: no-repeat;
    background-position: center center;
  }

  input:checked + label::before {
    border-color: #2196F3;
    background-image: url("../../img/shape.png");
  }
}
9
  • what is the problem? it seems to be working. Commented Sep 2, 2020 at 9:07
  • @Prateek Thapa, checkbox doesn't switch when I click Commented Sep 2, 2020 at 9:10
  • you mean the checkboxes are not checked when clicked? Commented Sep 2, 2020 at 9:12
  • @Prateek Thapa, yes Commented Sep 2, 2020 at 9:13
  • Create a sandbox just like that example? Commented Sep 2, 2020 at 9:15

1 Answer 1

1

Well, the problem is solved. It's all about input attributes. I was passing htmlFor property into ListItem for item.name, but not for id. So I needed to create an id property in my checkboxes array and pass htmlFor property like this htmlFor={item.id}

Don't forget to pass id property to ListItem as well like id={item.id}

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.