React:Composition

在日常的UI构建中,经常会遇到一种情况:组件本身更多是作为一个容器,它所包含的内容可能是动态的、未预先定义的。这时候它的内容取决另一个组件或外部的输入。比如弹层。

props.children:

React在组件中提供了props.children这个内置变量。当我们创建一个用作容器的组件时,在其返回的JSX中插入{props.children},此时{props.children}表示将来容器中需要插入的的内容。

比如我们创建一个带边框的div作为容器,

1 //一个带边框的div组件
2 function FancyBorder(props) {
3   return (
4     <div className={'FancyBorder FancyBorder-' + props.color}>
5       {props.children}
6     </div>
7   );
8 }

以后某个组件在输出的模板中调用了FancyBorder后,所有位于<FancyBorder></FancyBorder>标签内的内容将被看作FancyBorder组件的props.children。

 1 function WelcomeDialog() {
 2   return (
 3     <FancyBorder color="blue">
 4       <h1 className="Dialog-title">
 5         Welcome
 6       </h1>
 7       <p className="Dialog-message">
 8         Thank you for visiting our spacecraft!
 9       </p>
10     </FancyBorder>
11   );
12 }

当然,更普遍的情况是,我们要分发到容器上的内容,是需要指定位置的。

比如某段文字应该放在容器的右边,而某条评论或图片放在左边。这时候怎么办呢?

props.children给了我们启发。

JSX,也即要渲染的内容,可以作为参数prop传递给组件,然后在组件中恰当的位置进行渲染。要知道,React Element用typeof操作符判断时,其输出是‘object’,对象当然可以作为参数传递给函数啦!

 1 function SplitPane(props) {
 2   return (
 3     <div className="SplitPane">
 4       <div className="SplitPane-left">
 5         {props.left}
 6       </div>
 7       <div className="SplitPane-right">
 8         {props.right}
 9       </div>
10     </div>
11   );
12 }
13 
14 function App() {
15   return (
16     <SplitPane
17       left={
18         <Contacts />
19       }
20       right={
21         <Chat />
22       } />
23   );
24 }

这就解决了组件内容的嵌套和分发。

在React构建UI组件时,变量、方法、组件都可以作为props传递给子组件,实现单向的数据传输。

Specialization:定制化处理(我是这么理解啦)

我们常常需要用组件来实现一个特定的模块/视图。比如一个弹层,可以是警告,也可以是登陆框,更可以是某个内容展示。

既然我们可以通过props来分发内容,自然可以利用它来对定制一个符合我们期望的组件。

通过给容器传入各种参数、React Element,我们完全可以控制在模板的什么地方展示什么内容。这一切都通过props进行集合处理。

例子就不给了,跟上边一样,记住:

props.children分发容器标签之中的内容

props.xxx 分发其他指定内容