我正在尝试在codeandbox中创建嵌套的手风琴,以便对反应有更多的了解。我可以渲染嵌套的手风琴。手风琴可以打开和关闭。但是手风琴是重复的。
我创建了一个沙箱来显示工作示例
accordion.js
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";
}
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);
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,
...this.props
});
} else {
return child;
}
})}
</div>
);
}
}
AccordionItem.js
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;
有关嵌套手风琴的演示,这里是沙盒
答案 0 :(得分:1)
此街区
return React.cloneElement(child, {
expanded: this.isControlled
? child.props.expanded
: activeSections[child.props.name],
onToggle: this.onToggle,
...this.props
});
应如下所示:
return React.cloneElement(child, {
expanded: this.isControlled
? child.props.expanded
: activeSections[child.props.name],
onToggle: this.onToggle
});
因此,问题的根源在于您将父道具扩展为包括children
和header
属性的子道具。您可以(如果需要)从this.props
开始扩展,但是应该可以使用children
覆盖null
和使用header
覆盖child.props.header
(也许还有其他不应该进入儿童的道具)。