Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

React Checkbox component takes two clicks to change to checked

Tags:

reactjs

I have a React component that renders a checkbox. The problem is it takes two clicks to turned to checked and then two clicks to change to unchecked.

JS:

import React, { Component } from "react";

class CheckboxRow extends Component {
  constructor(props) {
    super(props);
    this.state = { checked: false };
  }

  inputChangedHandler() {
    this.setState({ checked: !this.state.checked });
  }

  render() {
    return (
      <div className="checkbox-row">
        <input
          id={this.props.id}
          type="checkbox"
          onChange={() => this.inputChangedHandler()}
          checked={this.state.checked}
        />
        <label htmlFor={this.props.id} className="checkbox-row__label">
          Label goes here
        </label>
      </div>
    );
  }
}

export default CheckboxRow;

So what do i need to do so that the checkbox turns to checked on one click and changes back to unchecked on one click?

like image 979
Mark Avatar asked Dec 11 '22 01:12

Mark


2 Answers

After staring at it for hours i had a eureka moment! I had a prevent.default() in the form onChange! Removing the prevent.default() fixed it Thanks to those that have replied.

like image 128
Mark Avatar answered Dec 12 '22 13:12

Mark


You should not access the old state directly when altering the state, like

this.setState({ checked: !this.state.checked });

instead do

this.setState(({ checked }) => ({ checked: !checked }));

Or you access the passed event from the onChange. Here written as a shorter functional component

function CheckboxRow({ id }) {
  const [checked, setChecked] = useState(false);

  const onChange = event => {
    event.persist();
    setChecked(event.target.checked);
  };

  return (
    <div className="checkbox-row">
      <input id={id} type="checkbox" onChange={onChange} checked={checked} />
      <label htmlFor={id} className="checkbox-row__label">
        Label goes here
      </label>
    </div>
  );
}
like image 30
Julian Kleine Avatar answered Dec 12 '22 14:12

Julian Kleine