有一类组件,充当了容器的作用,它定义了一种外层结构形式,然后你可以往里面塞任意的内容。这种结构在实际当中非常常见,类似于名片。这种组件本身是一个不带任何内容的方形的容器,我可以在用这个组件的时候给它传入任意内容。
先看一段这类容器类组件的实现代码:
class Card extends Component { render () { return ( <div className='card'> <div className='card-content'> {this.props.content} </div> </div> ) } } ReactDOM.render( <Card content={ <div> <h2>React.js 小书</h2> <div>开源、免费、专业、简单</div> 订阅:<input /> </div> } />, document.getElementById('root') )我们通过给 Card 组件传入一个 content 属性,这个属性可以传入任意的 JSX 结构。然后在 Card 内部会通过 {this.props.content} 把内容渲染到页面上。
这样明显太丑了,如果 Card 除了 content 以外还能传入其他属性的话,那么这些 JSX 和其他属性就会混在一起。很不好维护,如果能像下面的代码那样使用 Card 那想必也是极好的:
ReactDOM.render( <Card> /* 这里面是容器的children <h2>React.js 小书</h2> <div>开源、免费、专业、简单</div> 订阅:<input /> */ </Card>, document.getElementById('root') )如果组件标签也能像普通的 HTML 标签那样编写内嵌的结构,那么就方便很多了。实际上,React.js 默认就支持这种写法,所有嵌套在组件中的 JSX 结构都可以在组件内部通过 props.children 获取到:
class Card extends Component { render () { return ( <div className='card'> <div className='card-content'> {this.props.children} // 通过this.props.children获得传入组件标签的JSX内容 </div> </div> ) } }当我们打印出props.children,会发现它其实是个数组(包含了一个个的JSX元素):
既然返回了一个数组,那么数组内的JSX元素是否可以被单独拎出来使用呢,不得而知,是可以的:
class Layout extends Component { render () { return ( <div className='two-cols-layout'> <div className='sidebar'> {this.props.children[0]} </div> <div className='main'> {this.props.children[1]} </div> </div> ) } }这是一个两列布局组件,嵌套的 JSX 的第一个结构会成为侧边栏,第二个结构会成为内容栏,其余的结构都会被忽略。这样通过这个布局组件,就可以在各个地方高度复用我们的布局。
我们在使用自定义组件()的时候,可以在其中嵌套JSX结构,并在组件内部都可以通过 props.children 获取到被嵌套的JSX结构。
黑色边框的容器组件
css:
.border { border: 1px solid #000; }js:
class BlackBorderContainer extends Component { /* TODO */ render(){ return (<div>{this.props.children.map((item)=><div className="border">{item}</div>)}</div>) } }