Search code examples
reactjsreact-hooksreact-componentreact-functional-component

Convert Class component into a handleChange Hook


I'm wanting to convert this class component into a handleChange event that works in a function component. I'm not entirely sure that's possible, it may have to be a hook. I can't quite get the syntax right.

class CheckboxForm extends Component {
  constructor(props) {
    super(props);
    this.state = { value: [] };
    this.handleChange = this.handleChange.bind(this);
  }

  handleChange(event) {
    const input = event.target.value;
    this.setState(
      {
        value: this.state.value.includes(input)
          ? this.state.value.filter((item) => item !== input)
          : [...this.state.value, input],
      },
      () => {
        console.log("CheckBox: ", this.state.value);
      }
    );
  }

My attempt:

export const CheckboxHook = (props) => {
  const [value, setValue] = useState([]);
  const handleCheckbox = (event) => {
    const input = event.target.value;
    setValue(
      value.include(input)
        ? value.filter((item) => item !== input)
        : [value, input],
      () => {
        console.log("Checkbox: ", value);
      }
    );
  };
};

Solution

  • Seems like you're trying to do something like this? You don't need any custom hooks for it - just useState and useEffect.

    const CheckboxForm = (props) => {
      const [checkedItems, setCheckedItems] = useState([]);
    
      useEffect(() => {
        // equivalent to passing a callback to `this.setState` in class component
        console.log("Checked: ", checkedItems);
      }, [checkedItems])
    
      const handleCheckbox = (event) => {
        const { value } = event.target;
    
        // setting with hooks must use a callback
        // if you need access to the previous value
        setCheckedItems(items =>
          items.includes(value)
            ? items.filter(item => item !== value)
            : [...items, value]
        );
      };
    
      return <form>
        <label>a <input value="a" type="checkbox" onChange={handleCheckbox} /></label>
        <label>b <input value="b" type="checkbox" onChange={handleCheckbox} /></label>
        <label>c <input value="c" type="checkbox" onChange={handleCheckbox} /></label>
      </form>
    };