как выделить все checkbox по нажатию на главный

Может кто подскажет, при нажатие на checkbox - все. Меняю Стейт всех элементов и ожидаю что все элементы будет выполнены, Стейт меняется но элементы так и остаются в значение false(в DOM). Может использовать useEffect и отслеживать изменения стейт?

  useEffect(() => {
   (но что тогда прокинуть сюда)
}, [stops.stop]);

возможно, вообще я что-то делаю не так... Заранее спасибо.

Линк на демонстрацию: https://stackblitz.com/edit/react-x1jxw4?file=src%2FApp.js


Ответы (1 шт):

Автор решения: Избыток сусликов

Стейт меняется но элементы так и остаются в значение false(в DOM)

Это потому что вы неправильно их указали в атрибуте checked

Вы написали вот так

  <fieldset>
    <input
      type="checkbox"
      id="0"
      onChange={() => updateFiltersFunc(0)}
      checked={stops[0]}
    />
    <label htmlFor="0">0</label>
  </fieldset>

А в стейте вы храните объект внутри другого объекта

  const [stops, setStops] = useState({
    stop: {
      0: false,
      1: false,
      2: false,
      3: false,
    },
  });

Соответственно правильно будет вот так

  <fieldset>
    <input
      type="checkbox"
      id="0"
      onChange={() => updateFiltersFunc(0)}
      checked={stops.stop[0]}
    />
    <label htmlFor="0">0</label>
  </fieldset>

Также в других инпутах вы указываете не checked, а defaultChecked что тоже не правильно для правильного отображения логики вашего приложения

  <fieldset>
    <input
      type="checkbox"
      id="1"
      onChange={() => updateFiltersFunc(1)}
      defaultChecked={stops.stop[1]}
    />
    <label htmlFor="1">1</label>
  </fieldset>

Тут надо просто заменить defaultChecked на checked.

Вот рабочий код

Также переписал логику вашего приложения чуть по другому, так гораздо лучше, (не идеально конечно) чем дублировать постоянно этот объект.

stop: {
    0: false,
    1: false,
    2: false,
    3: false,
},

Новая версия

const App = () => {
  const [all, setAll] = useState(false);
  const [checkboxes, setCheckboxes] = useState([]);

  useEffect(() => {
    all ? setCheckboxes(['0', '1', '2', '3']) : setCheckboxes([]);
  }, [all]);


  const changeCheckboxes = (id) => {
    setCheckboxes(
      checkboxes.includes(id)
        ? checkboxes.filter((el) => el !== id)
        : [...checkboxes, id]
    );
  };

  return (
    <form action="" id={'ff'}>
      <fieldset>
        <input
          type="checkbox"
          id="all"
          onChange={() => setAll(!all)}
          checked={all}
        />
        <label htmlFor="all">Все</label>
      </fieldset>

      <fieldset>
        <input
          type="checkbox"
          id="0"
          onChange={(event) => changeCheckboxes(event.target.id)}
          checked={checkboxes.includes('0')}
        />
        <label htmlFor="0">0</label>
      </fieldset>

      <fieldset>
        <input
          type="checkbox"
          id="1"
          onChange={(event) => changeCheckboxes(event.target.id)}
          checked={checkboxes.includes('1')}
        />
        <label htmlFor="1">1</label>
      </fieldset>

      <fieldset>
        <input
          type="checkbox"
          id="2"
          onChange={(event) => changeCheckboxes(event.target.id)}
          checked={checkboxes.includes('2')}
        />
        <label htmlFor="2">2</label>
      </fieldset>

      <fieldset>
        <input
          type="checkbox"
          id="3"
          onChange={(event) => changeCheckboxes(event.target.id)}
          checked={checkboxes.includes('3')}
        />
        <label htmlFor="3">3</label>
      </fieldset>
    </form>
  );
};
→ Ссылка