applechips
applechips

Reputation: 23

Why isn't my Radio button clickable?

My radio button is not clickable. This is my component:

import React from 'react';
import { Form, Radio } from 'semantic-ui-react';
import PropTypes from 'prop-types';

const RadioButton = ({ name, label, className, value, onClick, checked, defaultValue }) => (
  <Form.Field>
    <Radio type="radio" label={label} defaultValue={defaultValue} value={value} name={name} className={className} onClick={onClick} checked={checked} />
  </Form.Field>
);

RadioButton.propTypes = {
  name: PropTypes.string.isRequired,
  label: PropTypes.string.isRequired,
  className: PropTypes.string,
  value: PropTypes.oneOfType([PropTypes.string, PropTypes.instanceOf(undefined)]),
  defaultValue: PropTypes.oneOfType([PropTypes.string, PropTypes.instanceOf(undefined)]),
  onClick: PropTypes.oneOfType([PropTypes.func, PropTypes.instanceOf(undefined)]),
  checked: PropTypes.bool,
};

RadioButton.defaultProps = {
  className: '',
  value: undefined,
  defaultValue: undefined,
  onClick: null,
  checked: false,
};

export default RadioButton;

I can't seem to understand why it's not working. Anyone have any ideas?

Upvotes: 1

Views: 848

Answers (1)

Andrew Li
Andrew Li

Reputation: 57964

You are permanently setting the checked prop to false, so the checkbox never changes checked state. To get it working, you need to control it's checked state through React and manage state in your component (so it can't be a stateless functional component). Here's a simple example:

class RadioButton extends React.Component {
  //you can statically set propTypes and defaultProps here if you prefer

  constructor(props) {
    super(props);
    this.handleClick = this.handleClick.bind(this);
    this.state = {
      checked: false
    };
  }

  handleClick() {
    this.setState(prevState => ({ //ensure correct previous state when async call is batched
      checked: !prevState.checked
    }));
    this.props.onClick && this.props.onClick(); //only execute if exists
  }

  render() {
    return (
      <Form.Field>
        <Radio {...this.props} onClick={this.handleClick} checked={this.state.checked} /> //{...this.props} passes props to Radio passed to RadioButton
      </Form.Field>
    );
  }
}

This will use state and manage checking and unchecking of the radio button. The checked prop isn't needed here anymore either.

A good rule of thumb is to ask yourself if the component is supposed to be interactive or change. If yes, then it must have internal state. In this case, the button must be checked and unchecked, which are two states. Thus you must manage internal state.

Upvotes: 3

Related Questions