React.js:状态未在父组件中更新

时间:2020-03-27 16:50:45

标签: reactjs

我有搜索过滤器和类别。我只想有可能在单页应用程序中重置状态。

由于React.js,我想我做了一切正确的工作,将状态从父级传递到子级,再从子级传递到父级。但是,不幸的是,出了点问题。我做了很多尝试,发现了DropdownGroup中的onAddCategory()不会更新当前状态。

对不起,我添加了整个代码,可能会影响到我。但是我想您可以看到两个代码的前半部分,这就足够了。

谢谢。

我有父级成员

class DropdownGroup extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      categories: [], // we have empty array, that pass to CategoryDropdown
    };
    this.onAddCategory = this.onAddCategory.bind(this);
  }

  onAddCategory(newCategory) {
    this.setState(() => ({
      categories: newCategory,
    }));
  }

  onSelectCategory(path) {
    this.props.onChangeEvents(path);
  }

  render() {
    const months = ['January', 'February' ... ];
    const eventsType = ['Party', 'Karaoke ... ];
    const { categories } = this.state;
    return (
      <ButtonToolbar className="justify-content-center pb-4 pt-4">

        { console.log(categories) }
        <CategoryDropdown
          items={eventsType}
          homePath="events"
          path="events/categories/"
          categories={categories} // here we pass our empty array (or updated later)
          addCategories={this.onAddCategory} // this is what helps to update our array
          onApply={(path) => this.onSelectCategory(path)}
        />

        <MyDropdown
          id="sort-by-month"
          name="By month"
          items={months}
          onSelect={(e) => this.onSelectCategory(`events/month/${e}`)}
        />

        <DropdownWithDate
          oneDate="events/date/"
          rangeDate="events/dates?from="
          onApply={(path) => this.onSelectCategory(path)}
        />

        <Button
          onClick={() => this.setState({ categories: [] })} // here we can reset the value of our array
          className="m-button ml-5"
        >
          Reset
        </Button>
      </ButtonToolbar>
    );
  }
}

DropdownGroup.propTypes = {
  onChangeEvents: PropTypes.any.isRequired,
};

export default DropdownGroup;

这是子组件

class CategoryDropdown extends Component {
  constructor(props) {
    super(props);
    this.state = {
      visible: false,
      selected: this.props.categories, // here we get values from props (now empty, then updated values)
    };
    this.onVisibleChange = this.onVisibleChange.bind(this);
  }

  onVisibleChange(visible) {
    this.setState({
      visible: visible,
    });
  }

  saveSelected(selectedKeys) {
    this.setState({
      selected: selectedKeys,
    });
  }

  addCategories() {
    this.props.addCategories(this.state.selected); // here props are updated
  }

  confirm() {
    const { selected } = this.state;
    this.addCategories(this.state.selected);
    const { homePath, path } = this.props;
    if (selected.length > 0) {
      this.props.onApply(path + selected);
    } else {
      this.props.onApply(homePath);
    }
    this.onVisibleChange(false);
  }

  render() {
    const { visible } = this.state;
    const { items } = this.props;
    const menu = (
      <Menu
        multiple
        onSelect={(e) => { this.saveSelected(e.selectedKeys); }}
        onDeselect={(e) => { this.saveSelected(e.selectedKeys); }}
      >
        {items.map((item) => (
          <MenuItem
            key={item.replace('\u0020', '\u005f').toLowerCase()}
          >
            {item}
          </MenuItem>
        ))}
        <Divider />
        <MenuItem disabled>
          <Container
            className="text-center "
            style={{
              cursor: 'pointer',
              pointerEvents: 'visible',
            }}
            onClick={() => {
              this.confirm();
            }}
          >
            Select
          </Container>
        </MenuItem>
      </Menu>
    );
    return (
      <Dropdown
        trigger={['click']}
        onVisibleChange={this.onVisibleChange}
        visible={visible}
        closeOnSelect={false}
        overlay={menu}
      >
        <Button className="m-button">By Category</Button>
      </Dropdown>
    );
  }
}

CategoryDropdown.propTypes = {
  onApply: PropTypes.any.isRequired,
  items: PropTypes.any.isRequired,
  path: PropTypes.string.isRequired,
  homePath: PropTypes.string.isRequired,
  categories: PropTypes.array.isRequired,
  addCategories: PropTypes.any.isRequired,
};

export default CategoryDropdown;

0 个答案:

没有答案
相关问题