从props.children中提取组件?

时间:2018-02-17 11:07:17

标签: javascript reactjs react-bootstrap styled-components

我正在使用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应该能够折叠除标题之外的所有内容。那么可以从Header中提取Panel内的this.props.children组件吗?如果是,那怎么办?

另外,如果我通过以下方式完成了这项工作:

  1. this.props.children
  2. 之前迭代child.type === Header
  3. 使用React.cloneElement分配新道具
  4. 并为这些新功能传递新的事件处理程序。
  5. 我在这里做错了吗?或者是否有一些优雅的方法来实现这一目标?

    谢谢。

2 个答案:

答案 0 :(得分:0)

您可以将其实现为高阶组件,将headerbody作为参数。您可以传递任何标题或正文,唯一的限制是该标题需要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"));

答案 1 :(得分:0)

如果您想从this.props.children

中提取组件

尝试使用功能作为子/渲染道具模式。

模式是这样的:

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>
  }
}

请参阅MyComponent只是一个将值传递给其函数的包装器。 在App组件中编写的函数只是一个无状态函数/组件,一个箭头函数返回一些 JSX

上面提到的 HOC模式也是一种方式。

这是关于这两种模式的已知主题。如果你还不确定,这篇文章可能会有些暗示:https://cdb.reacttraining.com/use-a-render-prop-50de598f11ce