user3545750
user3545750

Reputation: 51

Unable to set the checked state of the checkbox

I created a custom react component. I am able to fetch the state of the checkbox, when it is changed on a user action. However i am not able to set the checked state when i invoke the component and set the checked state to the prop. Here is my code

    import React, { FunctionComponent, SyntheticEvent, useState } from 'react';
import nanoid from 'nanoid';

import classNames from 'classnames';
import { mapToCssModules } from 'utils';
import VolumeComponentProps from 'utils/props';

export interface CheckboxProps extends VolumeComponentProps {
  /** Is selected */
  checked?: boolean;

  /** disabled - Sets or Gets the property if the input is disabled or not */
  disabled?: boolean;

  /** on Change event, raised when the input is clicked */
  onInputChange?: (e: SyntheticEvent, updatedState: boolean) => void;
}

export const Checkbox: FunctionComponent<CheckboxProps> = ({
  checked = false,
  children,
  className,
  cssModule,
  disabled = false,
  onInputChange,
  ...attributes
}: CheckboxProps) => {
  const valueCheck = checked ? true : false;
  const [inputId] = useState(`checkbox_${nanoid()}`);
  const [isChecked, setIsChecked] = useState(valueCheck);

  const containerClasses = mapToCssModules(classNames(className, 'vol-checkbox'), cssModule);
  const checkboxInputClass = mapToCssModules(classNames('vol-checkbox__input'), cssModule);
  const checkboxClass = mapToCssModules(classNames('vol-checkbox__input-control'), cssModule);

  const onChangeHandler = (e: SyntheticEvent) => {
    setIsChecked((e.currentTarget as HTMLInputElement).checked);
    if (onInputChange) {
      onInputChange(e, isChecked);
    }
  };

  return (
    <>
      {isChecked && <span>true</span>}
      <label className={containerClasses} htmlFor={inputId}>
        <input
          {...attributes}
          id={inputId}
          className={checkboxInputClass}
          disabled={disabled}
          checked={isChecked}
          type="checkbox"
          onChange={onChangeHandler}
        />
        <span className={checkboxClass} />
      </label>
    </>
  );
};

export default Checkbox;

So, if i invoke my checkbox as

<Checkbox onChange=()=>{} checked />

The checked value is not set to the checkbox, it works when i click it manually.

Update

This issue is only happening from Storybook. When i create a knob Checked, to alter states, that feature is not working. Here is my story.

import React from 'react';
import { storiesOf } from '@storybook/react';
import { boolean } from '@storybook/addon-knobs';
import { action } from '@storybook/addon-actions';

import Checkbox from './Checkbox';

storiesOf('Pure|Checkbox ', module).add(' Checkbox', () => {
  return (
    <Checkbox
      disabled={boolean('Disabled', false)}
      checked={boolean('Checked', false)}
      onInputChange={action('onChangeHandler')}
    />
  );
});

Upvotes: 1

Views: 1281

Answers (1)

technophyle
technophyle

Reputation: 9159

Your code should work, but you can simplify it by just toggling the isChecked state when the onChange event is fired. onChange means value changed and since a checked input has only two possible variables, we can safely assume that the value toggles, so no need to get the value from the event object each time.

Like this:

  const onChangeHandler = () => {
    setIsChecked(!isChecked);
    if (onInputChange) {
      onInputChange(e, !isChecked); // also, this line should pass the updated value
    }
  };

Upvotes: 1

Related Questions