component composition with props.children

function A({children}){

    console.log("A");

    const [state, setState]=useState(0);

    useEffect(()=>{

        setState((state)=>state+1);

    },[]);

    return children;

}

/* Here even on state change of `A` parent component, child components will not re-render. When the parent state changes, parent component re-renders. But it still has the same children prop it got last time, so React doesn’t visit that subtree. And as a result, child component doesn’t re-render.

 Thus there are two ways to prevent child components from re-rendering.

    - wrapping them in `memo`

    - passing them as `children` prop

*/


In JSX expressions, the content between an opening and closing tag is passed as a unique prop called children. There are several ways to pass children, such as rendering string literals or using JSX elements and JavaScript expressions. It is also essential to understand the types of JavaScript values that are ignored as children and don’t render anything.

Types of Children

String literals

String literals refer to simple JavaScript strings. They can be put between the opening and closing tags, and the children prop will be that string.

<MyComponent>Little Lemon</MyComponent>

In the above example, the children prop in MyComponent will be simply the string “Little Lemon”. 

JSX Elements

JavaScript Expressions

You can pass any JavaScript expression as children by enclosing it within curly braces, {}.

function Dessert(props) {

  return <li>{props.title}</li>;

}

function List() {

  const desserts = ['tiramisu', 'ice cream', 'cake'];

  return (

    <ul>

      {desserts.map((dessert) => <Item key={dessert} title={dessert} />)}

    </ul>

  );

}

Functions

Suppose you insert a JavaScript expression inside JSX. In that case, React will evaluate it to a string, a React element, or a combination of the two. However, the children prop works just like any other prop, meaning it can be used to pass any type of data, like functions.

Function as children is a React pattern used to abstract shared functionality that you will see in detail in the next lesson.

Booleans, Null and Undefined, are ignored

false, null, undefined, and true are all valid children. They simply don’t render anything. The below expressions will all render the same thing:

<div />

<div></div>

<div>{false}</div>

<div>{null}</div>

<div>{undefined}</div>

<div>{true}</div>

Again, this is all for demonstration purposes so that you know what to expect on your screen when these special values are used in your JSX. 

When used in isolation, they don’t offer any value. However, boolean values like true and false can be useful to conditionally render React elements, like rendering a Modal component only if the variable showModal is true:

<div>

  {showModal && <Modal />}

</div>

However, keep in mind that React still renders some "false" values, like the 0 number. For example, the below code will not behave as you may expect because 0 will be printed when props.desserts is an empty array:

<div>

  {props.desserts.length &&

    <DessertList desserts={props.desserts} />

  }

</div>

To fix this, you need to make sure the expression before && is always boolean:

<div>

  {props.desserts.length > 0 &&

    <DessertList desserts={props.desserts} />

  }

</div>

<div>

  {!!props.desserts.length &&

    <DessertList desserts={props.desserts} />

  }

</div>


The children prop which is a special property all components have, is the foundation for the React powerful composition model. 

上层组件传下的属性,下层组件无法提前预知,但依然可以组合

function Bag(props) {

    const bag = {

        padding: "20px",

        border: "1px solid gray",

        background: "#fff",

        margin: "20px 0"

    }

    return (

        <div style={bag}>

            {props.children}

        </div>

    )

}

export default Bag


There are two main features that enable component composition; containment and specialization. 

Containment refers to the fact that some components don't know their children ahead of time. 

This is especially common for components like a sidebar or a dialog, where they delimit a specific area in your UI to contain other elements. You can think of them also as generic boxes. 

In case you don't know, a dialog is a type of modal window where the rest of the UI is disabled until the modal is addressed and interacted with. 

For these component boxes, the recommended approach is to use the children prop to pass children elements directly as their content. 

Let's explore this with a dialog example. 

containment example: dialog无法提前预知props.children

Here you have a dialog component which acts as the box, taking care of styling the container to make it look like a modal window. By using the children prop, it has become a generic component to which we can provide any valid JSX as children. 

To illustrate that, the confirmation dialog component has been defined, which uses the dialog component and renders as children a title and a description. 

children composition

This example also showcases the second feature of component composition, specialization. Specialization defines components as being special cases of other components. In this example, the confirmation dialog is a special case of dialog.


But what is this props.children?

<Example>

    Hello there

</Example>

The Hello there text is a child of the Example JSX element. The Example JSX Element above is an "invocation" of the Example.js file, which, in modern React, is usually a function component.

Now, did you know that this Hello there piece of text can be passed as a named prop when rendering the Example component?

Here's how that would look like:

<Example children="Hello there" />

Ok, so, there are two ways to do it. But this is just the beginning.

What if you, say, wanted to surround the Hello there text in an h3 HTML element?

Obviously, in JSX, that is easily achievable:

<Example children={<h3>Hello there</h3>} />

What if the <h3>Hello there</h3> was a separate component, for example, named Hello?

In that case, you'd have to update the code like this:

<Example children={<Hello />} />

You could even make the Hello component more dynamic, by giving it its own prop:

<Example children={<Hello message="Hello there" />} />


In JS, B is a function. B will only evaluate when we call it. B()

We are passing B function in A. It will pass without running.

When we return children react will execute the B.


props.children.map函数来遍历会收到异常提示,为什么?应该如何遍历?

this.props.children的值有三种可能:

1.当前组件没有子节点,它是undefined;

2.有一个子节点,数据类型是object ;

3.有多个子节点,数据类型就是array 。

react提供React.Children.map(children, callback)安全的遍历子节点

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,137评论 6 511
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,824评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,465评论 0 357
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,131评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,140评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,895评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,535评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,435评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,952评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,081评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,210评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,896评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,552评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,089评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,198评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,531评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,209评论 2 357

推荐阅读更多精彩内容