2

Using react-bootstrap to make a dropdown with a list of checkboxes. When I click the checkboxes the toggle event works but component is not re-rendered and the checkbox does not change.

Here is the dropdown component:

type Props = {
  checkboxList: Array<string>;
  title: ReactNode;
  activeCheckboxes: Array<string>;
  onToggle: (string) => void;
  textFormatter: (string) => string;
}

type State = {
  open: boolean;
  activeCheckboxes: Array<string>;
}

class CheckboxDropdown extends React.PureComponent<Props, State> {
  static propsType = {
    checkboxList: PropTypes.array,
    title: PropTypes.string,
    activeCheckboxes: PropTypes.array,
    onToggle: PropTypes.func,
  }

  state: State2;

  constructor(props) {
    super(props);
    this.state = {
      open: false,
      activeCheckboxes: this.props.activeCheckboxes
    };
  }

  static getDerivedStateFromProps(props, state): any {
    if (props.activeCheckboxes.length !== state.activeCheckboxes.length) {
      return {
        activeCheckboxes: props.activeCheckboxes
      };
    }
    return null;
  }

  handleToggle(isOpen, event, metadata): void {
    if (isOpen || metadata.source !== 'select') {
      this.setState(() => ({ open: isOpen }));
    }
    if (event) {
      event.persist();
    }
  }

  render(): ReactNode {
    const { open, activeCheckboxes } = this.state;
    const { checkboxList, title, onToggle, textFormatter } = this.props;

    return (
      <Dropdown
        show={open}
        onToggle={this.handleToggle.bind(this)}
      >
        <Dropdown.Toggle id="dropdown-basic">
          {title}
        </Dropdown.Toggle>
        <Dropdown.Menu>
          {checkboxList.map((chkBox) => (
            <Dropdown.Item key={chkBox}>
              <input type="checkbox" onChange={() => onToggle(chkBox)} checked={activeCheckboxes.includes(chkBox)} />{chkBox}
            </Dropdown.Item>
          ))}
        </Dropdown.Menu>
      </Dropdown>
    );
  }
}

Usage:

     <CheckboxDropdown 
       checkboxList={FILTER_LIST}
       activeCheckboxes={activeFilter}
       title={"Dropdown"} />}
       onToggle={this.onToggleCheckbox.bind(this)}
     />

Toggle checkbox updates activeFilters. How can I fix this so when activeFilters changes the checkboxes update?

Connor
  • 61
  • 1
  • 8

1 Answers1

0

I am not exactly sure how this solution is working. I am observing changing the onChange to onClick in the input and stopping event propagation is updating the checkbox. https://codesandbox.io/s/frosty-bhabha-irhxc

< input
type = "checkbox"
onClick = {
  e => {
    onToggle(chkBox);
    e.stopPropagation();
  }
}
checked = {
  activeCheckboxes.includes(chkBox)
}
/>
vishnu sandhireddy
  • 1,148
  • 1
  • 7
  • 12
  • That does seem to work for me but I feel like it is not an idea solution as it creates a warning about using `checked` without and `onChange` handler. It recommends using `defaultChecked`. I don't want to use that because I still want the value of the checkbox to respond to state changes as well as clicking on it. – Connor Mar 18 '20 at 21:16