Checkbox неправильно меняется в React

function App() {
  const [state, setState] = useState(false);
  const input = React.createRef()
  const input2 = React.createRef()

  function handleClick() {
    setState(input2.current.value)
  }

  return (
    <>
      <input type="checkbox" ref={input} checked={state}/>
      <select ref={input2} onChange={handleClick}>
        <option value={false}>OFF</option>
        <option value={true}>ON</option>
      </select>
    </>
  );
}

Нужно при соответствуещем выбраном поле в select делать checkbox вкл или выкл. Но вылазит такая ошибка (уведомление)

Warning: Received the string true for the boolean attribute checked. Although this works, it will not work as expected if you pass the string "false". Did you mean checked={true}?


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

Автор решения: EzioMercer

Пару замечаний:

  • Чисто в этом компоненте вам не нужны ref-ы вообще (если конечно - это полный код компоненты)
  • В каком бы виде вы не писали в value, тега option данные, они всегда будут в строчном виде (сделал вывод в консоль чтобы убедились в этом). По этой причине вам на вход приходили не true и false, а "true" и "false". И как мы знаем в JS НЕ пустая строка при конвертации в булевую переменную всегда даст true, следовательно checkbox всегда будет помеченным, кроме как начального состояния т.к. там действительно сначала стоит булевая переменная false
  • Проверять условие в самом аттрибуте не стоит. Не то чтобы это не будет работать, а так код будет чище и понятнее, если handleClick сам займётся всеми нужными преобразованиями и уже вставит нужное значение
  • Писать проверку типа x === y ? true : false бессмысленно, т.к. x === y и так вернёт вам true, если они равны и false. если они не равны

Код:

const {useState} = React;

function App() {
  const [state, setState] = useState(false);

  function handleClick(e) {
    const value = e.target.value;
    
    console.log(value, typeof value);
    setState(value === 'true');
  }

  return (
    <React.Fragment>
      <input type="checkbox" checked={state}/>
      <select onChange={handleClick}>
        <option value={false}>OFF</option>
        <option value={true}>ON</option>
      </select>
    </React.Fragment>
  );
}

ReactDOM.render(
  <App />,
  document.getElementById('react')
);
<div id="react"></div>

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/18.1.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/18.1.0/umd/react-dom.production.min.js"></script>

→ Ссылка