React Bootstrap Dropdown items does not update on state change

Viewed 1074

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?

1 Answers

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)
}
/>

Related