[英]Extracting a component from props.children?
I was working on a Panel
component in ReactJS, and so, idea is to make the basic components available along with the collapse/close functionality. 我当时在ReactJS中使用
Panel
组件,因此,想法是使基本组件与折叠/关闭功能一起可用。 However, I am unable to find any way to extract a component from this.props.children
. 但是,我找不到任何从
this.props.children
提取组件的this.props.children
。
So here is my component: 所以这是我的组件:
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;
So, now the user of this component can do something like: 因此,现在该组件的用户可以执行以下操作:
<Panel>
<Panel.Header>Header text for this panel</Panel.Header>
<Panel.Body>Body of this panel</Panel.Body>
</Panel>
Header
component contains a toolbar control for collapse and close functionalities. Header
组件包含用于折叠和关闭功能的工具栏控件。 Now I do understand that the user of this component can specify these event handlers, and implement these features. 现在,我知道该组件的用户可以指定这些事件处理程序,并实现这些功能。 But I want this out of the box.
但我想开箱即用。 So,
Panel
by default, should be able to collapse everything except the header. 因此,
Panel
默认情况下应该能够折叠标题以外的所有内容。 So is it possible to extract Header
component inside the Panel
from this.props.children
? 那么可以从
this.props.children
提取Panel
内部的Header
组件吗? If yes, then how? 如果是,那怎么办?
Also, if I did make this work by: 另外,如果我确实通过以下方式进行了此项工作:
this.props.children
until child.type === Header
this.props.children
直到child.type === Header
React.cloneElement
to assign new props React.cloneElement
分配新道具 Am I doing something wrong here? 我在这里做错什么了吗? Or is there some elegant way to achieve this?
还是有一些优雅的方法来实现这一目标?
Thank you. 谢谢。
You could implement it as a higher-order component which would take header
and body
as parameters. 您可以将其实现为一个高阶组件,该组件将
header
和body
作为参数。 You could pass any header or body, the only restriction would be that header requires an onOpenChanged
callback prop
. 您可以传递任何标头或正文,唯一的限制是标头需要
onOpenChanged
回调prop
。
Here is a working sandbox . 这是一个工作中的沙箱 。
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"));
In case you want to extract a component from this.props.children
, 如果要从
this.props.children
提取组件,
try to use Function as a Child / Render props pattern. 尝试使用“ 功能作为子代/渲染道具”模式。
the pattern is like this: 模式是这样的:
class MyComponent extends Component {
state = {
bgcolor: 'red'
}
render(){
<div>
{ this.props.children(this.state.bgcolor)}
</div>
}
}
class App exnted Component {
render(){
<MyComponent>
{ bgColor => <Header bgcolor={bgColor} /> }
</MyComponent>
}
}
See MyComponent
is just a wrapper that passes a value to its function. 请参见
MyComponent
只是将值传递给其函数的包装器。 The function as written inside App
component is just a stateless function/component, an arrow function that returns some JSX . App
组件内部编写的函数只是一个无状态函数/组件,一个返回一些JSX的箭头函数。
The HOC pattern as mantioned above is also a way. 上面提到的HOC模式也是一种方法。
This is a known topic about those 2 patterns. 这是关于这两种模式的已知主题。 This article might shad some light in case your are not yet sure: https://cdb.reacttraining.com/use-a-render-prop-50de598f11ce
如果您不确定,本文可能会有所帮助: https : //cdb.reacttraining.com/use-a-render-prop-50de598f11ce
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.