仅在打开父级手风琴时显示子级手风琴

时间:2018-11-01 00:43:03

标签: javascript reactjs

我正在开发一种嵌套在字符中的手风琴。我的意思是,手风琴也可以有其子手风琴。现在,已经建立了一个简单的手风琴。切换部分也可以。但是,有一个问题。显示的儿童手风琴没有打开父手风琴。我该如何仅在单击父手风琴时显示子手风琴并在再次单击时将其隐藏?

这就是我所做的

class Accordion extends React.Component {
  constructor(props) {
    super(props);
    let state = { activeSections: {} };

    React.Children.toArray(props.children).forEach(child => {
      if (child) {
        state.activeSections[child.props.name] = !!child.props.defaultOpen;
      }
    });

    this.state = state;
  }
  get isControlled() {
    return typeof this.props.onToggle === "function";
  }
  expandAll = () => {
    if (this.isControlled) {
      this.props.expandAll();
    } else {
      let { activeSections } = this.state;
      Object.keys(activeSections).forEach(k => (activeSections[k] = true));
      this.setState({ activeSections });
    }
  };
  collapseAll = () => {
    if (this.isControlled) {
      this.props.collapseAll();
    } else {
      let { activeSections } = this.state;
      Object.keys(activeSections).forEach(k => (activeSections[k] = false));
      this.setState({ activeSections });
    }
  };
  onToggle = name => {
    if (this.isControlled) {
      this.props.onToggle(name);
    } else {
      let activeSections = this.state.activeSections;
      this.setState({
        activeSections: { ...activeSections, [name]: !activeSections[name] }
      });
    }
  };
  componentWillReceiveProps(nextProps) {
    let { activeSections } = this.state;

    React.Children.toArray(nextProps.children)
      .filter(c => c)
      .forEach(child => {
        if (activeSections[child.props.name] == null) {
          activeSections[child.props.name] = !!child.props.defaultOpen;
        }
      });
    this.setState({ activeSections });
  }
  render() {
    let { activeSections } = this.state;
    let children = React.Children.toArray(this.props.children);

    // if (!children.find(c => c && c.type === AccordionHeader)) {
    //   children = [<AccordionHeader />, ...children];
    // }
    console.log("children", children);
    return (
      <div>
        {children.map(child => {
          if (!child) {
            return child;
          } else if (child.type === AccordionItem) {
            return React.cloneElement(child, {
              expanded: this.isControlled
                ? child.props.expanded
                : activeSections[child.props.name],
              onToggle: this.onToggle
            });
          } else {
            return child;
          }
        })}
      </div>
    );
  }
}

export default Accordion;





class AccordionItem extends React.Component {
  render() {
    let {
      expanded,
      caption,
      onToggle,
      name,
      children,
      render,
      ...rest
    } = this.props;
    return render ? (
      render({ onToggle: onToggle.bind(null, name), expanded })
    ) : (
      <styled.AccordionItem style={{ margin: 10 }}>
        <styled.AccordionHeader
          onClick={() => onToggle(name)}
          active={expanded}
        >
          {caption}
        </styled.AccordionHeader>
        <styled.AccordionBody active={rest.defaultOpen || expanded}>
          {children && (
            <styled.AccordionBodyContent>
              {children}
            </styled.AccordionBodyContent>
          )}
        </styled.AccordionBody>
      </styled.AccordionItem>
    );
  }
}

export default AccordionItem;

我已经在沙箱中创建了一个工作示例,这里是

https://codesandbox.io/s/z25j8q2v4m

0 个答案:

没有答案