我正在 ReactJS 中开发一个 Panel
组件,因此,想法是使基本组件与折叠/关闭功能一起可用。但是,我无法找到任何方法从 this.props.children
中提取组件。
这是我的组件:
import React, { Component } from 'react';
import Header from './PanelHeader';
import Body from './PanelBody';
class Panel extends React.Component {
constructor(props) {
super(props);
this.state = { open: true };
}
render() {
return (
<StyledPanel>
{this.props.children} <-- Is there a way to extract the Header component here
</StyledPanel>
);
}
}
Object.assign(Panel,
{
Header,
Body
});
export default Panel;
因此,现在该组件的用户可以执行以下操作:
<Panel>
<Panel.Header>Header text for this panel</Panel.Header>
<Panel.Body>Body of this panel</Panel.Body>
</Panel>
Header
组件包含用于折叠和关闭功能的工具栏控件。现在我确实明白该组件的用户可以指定这些事件处理程序,并实现这些功能。但我想要这个开箱即用。因此,默认情况下,Panel
应该能够折叠除标题之外的所有内容。那么是否可以从 this.props.children
中提取 Panel
内的 Header
组件呢?如果是,那么如何?
此外,如果我确实通过以下方式完成这项工作:
- 迭代
this.props.children
直到child.type === Header
- 使用
React.cloneElement
分配新的 props - 并为这些新功能传入新的事件处理程序。
我在这里做错了什么吗?或者有一些优雅的方法来实现这一点吗?
谢谢。
最佳答案
您可以将其实现为一个高阶组件,该组件将 header
和 body
作为参数。您可以传递任何 header 或正文,唯一的限制是 header 需要 onOpenChanged
回调 prop
。
这是一个工作 sandbox .
链接到HOC
const Header = (props) =>{
const { onOpenChanged } = props;
return <div onClick={onOpenChanged}>Header text for this panel</div>;
}
const Body = () => <div>Body of this panel</div>;
const stylishPanel = (WrappedHeader, WrappedBody) => {
return class extends React.Component {
constructor(props) {
super(props);
this.state = {
isOpen: true
};
}
handleToggleOpen = () => {
this.setState(({ isOpen }) => ({
isOpen: !isOpen
}));
};
render() {
const { isOpen } = this.state;
// your styled-panel instead of div
return (
<div className="super-panel">
<WrappedHeader onOpenChanged={this.handleToggleOpen} />
{isOpen && <WrappedBody />}
</div>
);
}
};
};
const App = () => {
const SuperPanel = stylishPanel(Header, Body);
return (
<div style={styles}>
<SuperPanel />
</div>
);
};
render(<App />, document.getElementById("root"));
关于javascript - 从 props.children 中提取组件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48840633/