React elements can have zero, one, or many children. Being able to type these
children with Flow allows you to build expressive APIs with React children.
Generally, the type you should first try when adding a type for the children of
your React component is React.Node
.
Like this:
1
2
3
4
5
6
7
8
9
|
import * as React from 'react';
type Props = {
children?: React.Node,
};
function MyComponent(props: Props) {
return <div>{props.children}</div>;
}
|
{"value":"import * as React from 'react';\n\ntype Props = {\n children?: React.Node,\n};\n\nfunction MyComponent(props: Props) {\n return <div>{props.children}</div>;\n}\n","tokens":[{"type":"T_IMPORT","context":"normal","value":"import","line":1,"start":0,"end":6},{"type":"T_MULT","context":"normal","value":"*","line":1,"start":7,"end":8},{"type":"T_IDENTIFIER","context":"normal","value":"as","line":1,"start":9,"end":11},{"type":"T_IDENTIFIER","context":"normal","value":"React","line":1,"start":12,"end":17},{"type":"T_IDENTIFIER","context":"normal","value":"from","line":1,"start":18,"end":22},{"type":"T_STRING","context":"normal","value":"'react'","line":1,"start":23,"end":30},{"type":"T_SEMICOLON","context":"normal","value":";","line":1,"start":30,"end":31},{"type":"T_TYPE","context":"normal","value":"type","line":3,"start":33,"end":37},{"type":"T_IDENTIFIER","context":"type","value":"Props","line":3,"start":38,"end":43},{"type":"T_ASSIGN","context":"type","value":"=","line":3,"start":44,"end":45},{"type":"T_LCURLY","context":"type","value":"{","line":3,"start":46,"end":47},{"type":"T_IDENTIFIER","context":"normal","value":"children","line":4,"start":50,"end":58},{"type":"T_PLING","context":"type","value":"?","line":4,"start":58,"end":59},{"type":"T_COLON","context":"type","value":":","line":4,"start":59,"end":60},{"type":"T_IDENTIFIER","context":"type","value":"React","line":4,"start":61,"end":66},{"type":"T_PERIOD","context":"type","value":".","line":4,"start":66,"end":67},{"type":"T_IDENTIFIER","context":"type","value":"Node","line":4,"start":67,"end":71},{"type":"T_COMMA","context":"type","value":",","line":4,"start":71,"end":72},{"type":"T_RCURLY","context":"type","value":"}","line":5,"start":73,"end":74},{"type":"T_SEMICOLON","context":"normal","value":";","line":5,"start":74,"end":75},{"type":"T_FUNCTION","context":"normal","value":"function","line":7,"start":77,"end":85},{"type":"T_IDENTIFIER","context":"normal","value":"MyComponent","line":7,"start":86,"end":97},{"type":"T_LPAREN","context":"normal","value":"(","line":7,"start":97,"end":98},{"type":"T_IDENTIFIER","context":"normal","value":"props","line":7,"start":98,"end":103},{"type":"T_COLON","context":"type","value":":","line":7,"start":103,"end":104},{"type":"T_IDENTIFIER","context":"type","value":"Props","line":7,"start":105,"end":110},{"type":"T_RPAREN","context":"normal","value":")","line":7,"start":110,"end":111},{"type":"T_LCURLY","context":"normal","value":"{","line":7,"start":112,"end":113},{"type":"T_RETURN","context":"normal","value":"return","line":8,"start":116,"end":122},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":8,"start":123,"end":124},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"div","line":8,"start":124,"end":127},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":8,"start":127,"end":128},{"type":"T_LCURLY","context":"normal","value":"{","line":8,"start":128,"end":129},{"type":"T_IDENTIFIER","context":"normal","value":"props","line":8,"start":129,"end":134},{"type":"T_PERIOD","context":"normal","value":".","line":8,"start":134,"end":135},{"type":"T_IDENTIFIER","context":"normal","value":"children","line":8,"start":135,"end":143},{"type":"T_RCURLY","context":"normal","value":"}","line":8,"start":143,"end":144},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":8,"start":144,"end":145},{"type":"T_DIV","context":"jsxTag","value":"/","line":8,"start":145,"end":146},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"div","line":8,"start":146,"end":149},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":8,"start":149,"end":150},{"type":"T_SEMICOLON","context":"normal","value":";","line":8,"start":150,"end":151},{"type":"T_RCURLY","context":"normal","value":"}","line":9,"start":152,"end":153}],"errors":[]}
Note: You need to use import * as React from 'react'
here instead of
import React from 'react'
to get access to the
React.Node
type. We explain why that is in the
React Type Reference.
However, if you want to do anything more powerful with the React children API
then you will need a strong intuition of how React handles children. Let us look
at a couple of cases before continuing to help build that intuition.
If you already have a strong intuition about how React children work then feel
free to skip to our examples demonstrating how to type various children
patterns that commonly show up in React components.
Our first case is an element with no children:
1
2
3
4
|
<MyComponent />;
React.createElement(MyComponent, {});
|
{"value":"<MyComponent />;\n\n// which is the same as...\nReact.createElement(MyComponent, {});\n","tokens":[{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":1,"start":0,"end":1},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"MyComponent","line":1,"start":1,"end":12},{"type":"T_DIV","context":"jsxTag","value":"/","line":1,"start":13,"end":14},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":1,"start":14,"end":15},{"type":"T_SEMICOLON","context":"normal","value":";","line":1,"start":15,"end":16},{"type":"Line","context":"comment","value":"// which is the same as...","line":3,"start":18,"end":44},{"type":"T_IDENTIFIER","context":"normal","value":"React","line":4,"start":45,"end":50},{"type":"T_PERIOD","context":"normal","value":".","line":4,"start":50,"end":51},{"type":"T_IDENTIFIER","context":"normal","value":"createElement","line":4,"start":51,"end":64},{"type":"T_LPAREN","context":"normal","value":"(","line":4,"start":64,"end":65},{"type":"T_IDENTIFIER","context":"normal","value":"MyComponent","line":4,"start":65,"end":76},{"type":"T_COMMA","context":"normal","value":",","line":4,"start":76,"end":77},{"type":"T_LCURLY","context":"normal","value":"{","line":4,"start":78,"end":79},{"type":"T_RCURLY","context":"normal","value":"}","line":4,"start":79,"end":80},{"type":"T_RPAREN","context":"normal","value":")","line":4,"start":80,"end":81},{"type":"T_SEMICOLON","context":"normal","value":";","line":4,"start":81,"end":82}],"errors":[]}
If you pass in no children when creating an element of MyComponent
then
props.children
will not be set. If you try to access props.children
, it
will be undefined.
What happens when you have a single child?
1
2
3
4
|
<MyComponent>{42}</MyComponent>;
React.createElement(MyComponent, {}, 42);
|
{"value":"<MyComponent>{42}</MyComponent>;\n\n// which is the same as...\nReact.createElement(MyComponent, {}, 42);\n","tokens":[{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":1,"start":0,"end":1},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"MyComponent","line":1,"start":1,"end":12},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":1,"start":12,"end":13},{"type":"T_LCURLY","context":"normal","value":"{","line":1,"start":13,"end":14},{"type":"T_NUMBER","context":"normal","value":"42","line":1,"start":14,"end":16},{"type":"T_RCURLY","context":"normal","value":"}","line":1,"start":16,"end":17},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":1,"start":17,"end":18},{"type":"T_DIV","context":"jsxTag","value":"/","line":1,"start":18,"end":19},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"MyComponent","line":1,"start":19,"end":30},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":1,"start":30,"end":31},{"type":"T_SEMICOLON","context":"normal","value":";","line":1,"start":31,"end":32},{"type":"Line","context":"comment","value":"// which is the same as...","line":3,"start":34,"end":60},{"type":"T_IDENTIFIER","context":"normal","value":"React","line":4,"start":61,"end":66},{"type":"T_PERIOD","context":"normal","value":".","line":4,"start":66,"end":67},{"type":"T_IDENTIFIER","context":"normal","value":"createElement","line":4,"start":67,"end":80},{"type":"T_LPAREN","context":"normal","value":"(","line":4,"start":80,"end":81},{"type":"T_IDENTIFIER","context":"normal","value":"MyComponent","line":4,"start":81,"end":92},{"type":"T_COMMA","context":"normal","value":",","line":4,"start":92,"end":93},{"type":"T_LCURLY","context":"normal","value":"{","line":4,"start":94,"end":95},{"type":"T_RCURLY","context":"normal","value":"}","line":4,"start":95,"end":96},{"type":"T_COMMA","context":"normal","value":",","line":4,"start":96,"end":97},{"type":"T_NUMBER","context":"normal","value":"42","line":4,"start":98,"end":100},{"type":"T_RPAREN","context":"normal","value":")","line":4,"start":100,"end":101},{"type":"T_SEMICOLON","context":"normal","value":";","line":4,"start":101,"end":102}],"errors":[]}
If you pass in a single value then props.children
will be exactly that
single value. Here props.children
will be the number 42. Importantly,
props.children
will not be an array! It will be exactly the number 42.
What happens when you have multiple children?
1
2
3
4
|
<MyComponent>{1}{2}</MyComponent>;
React.createElement(MyComponent, {}, 1, 2);
|
{"value":"<MyComponent>{1}{2}</MyComponent>;\n\n// which is the same as...\nReact.createElement(MyComponent, {}, 1, 2);\n","tokens":[{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":1,"start":0,"end":1},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"MyComponent","line":1,"start":1,"end":12},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":1,"start":12,"end":13},{"type":"T_LCURLY","context":"normal","value":"{","line":1,"start":13,"end":14},{"type":"T_NUMBER","context":"normal","value":"1","line":1,"start":14,"end":15},{"type":"T_RCURLY","context":"normal","value":"}","line":1,"start":15,"end":16},{"type":"T_LCURLY","context":"normal","value":"{","line":1,"start":16,"end":17},{"type":"T_NUMBER","context":"normal","value":"2","line":1,"start":17,"end":18},{"type":"T_RCURLY","context":"normal","value":"}","line":1,"start":18,"end":19},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":1,"start":19,"end":20},{"type":"T_DIV","context":"jsxTag","value":"/","line":1,"start":20,"end":21},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"MyComponent","line":1,"start":21,"end":32},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":1,"start":32,"end":33},{"type":"T_SEMICOLON","context":"normal","value":";","line":1,"start":33,"end":34},{"type":"Line","context":"comment","value":"// which is the same as...","line":3,"start":36,"end":62},{"type":"T_IDENTIFIER","context":"normal","value":"React","line":4,"start":63,"end":68},{"type":"T_PERIOD","context":"normal","value":".","line":4,"start":68,"end":69},{"type":"T_IDENTIFIER","context":"normal","value":"createElement","line":4,"start":69,"end":82},{"type":"T_LPAREN","context":"normal","value":"(","line":4,"start":82,"end":83},{"type":"T_IDENTIFIER","context":"normal","value":"MyComponent","line":4,"start":83,"end":94},{"type":"T_COMMA","context":"normal","value":",","line":4,"start":94,"end":95},{"type":"T_LCURLY","context":"normal","value":"{","line":4,"start":96,"end":97},{"type":"T_RCURLY","context":"normal","value":"}","line":4,"start":97,"end":98},{"type":"T_COMMA","context":"normal","value":",","line":4,"start":98,"end":99},{"type":"T_NUMBER","context":"normal","value":"1","line":4,"start":100,"end":101},{"type":"T_COMMA","context":"normal","value":",","line":4,"start":101,"end":102},{"type":"T_NUMBER","context":"normal","value":"2","line":4,"start":103,"end":104},{"type":"T_RPAREN","context":"normal","value":")","line":4,"start":104,"end":105},{"type":"T_SEMICOLON","context":"normal","value":";","line":4,"start":105,"end":106}],"errors":[]}
Now, if you pass two values then props.children
will be an array. Specifically
in this case props.children
will be [1, 2]
.
Multiple children may also look like:
1
2
3
4
|
<MyComponent>{'hello'} world</MyComponent>;
React.createElement(MyComponent, {}, 'hello', ' world');
|
{"value":"<MyComponent>{'hello'} world</MyComponent>;\n\n// which is the same as...\nReact.createElement(MyComponent, {}, 'hello', ' world');\n","tokens":[{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":1,"start":0,"end":1},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"MyComponent","line":1,"start":1,"end":12},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":1,"start":12,"end":13},{"type":"T_LCURLY","context":"normal","value":"{","line":1,"start":13,"end":14},{"type":"T_STRING","context":"normal","value":"'hello'","line":1,"start":14,"end":21},{"type":"T_RCURLY","context":"normal","value":"}","line":1,"start":21,"end":22},{"type":"T_JSX_TEXT","context":"jsxChild","value":" world","line":1,"start":22,"end":28},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":1,"start":28,"end":29},{"type":"T_DIV","context":"jsxTag","value":"/","line":1,"start":29,"end":30},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"MyComponent","line":1,"start":30,"end":41},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":1,"start":41,"end":42},{"type":"T_SEMICOLON","context":"normal","value":";","line":1,"start":42,"end":43},{"type":"Line","context":"comment","value":"// which is the same as...","line":3,"start":45,"end":71},{"type":"T_IDENTIFIER","context":"normal","value":"React","line":4,"start":72,"end":77},{"type":"T_PERIOD","context":"normal","value":".","line":4,"start":77,"end":78},{"type":"T_IDENTIFIER","context":"normal","value":"createElement","line":4,"start":78,"end":91},{"type":"T_LPAREN","context":"normal","value":"(","line":4,"start":91,"end":92},{"type":"T_IDENTIFIER","context":"normal","value":"MyComponent","line":4,"start":92,"end":103},{"type":"T_COMMA","context":"normal","value":",","line":4,"start":103,"end":104},{"type":"T_LCURLY","context":"normal","value":"{","line":4,"start":105,"end":106},{"type":"T_RCURLY","context":"normal","value":"}","line":4,"start":106,"end":107},{"type":"T_COMMA","context":"normal","value":",","line":4,"start":107,"end":108},{"type":"T_STRING","context":"normal","value":"'hello'","line":4,"start":109,"end":116},{"type":"T_COMMA","context":"normal","value":",","line":4,"start":116,"end":117},{"type":"T_STRING","context":"normal","value":"' world'","line":4,"start":118,"end":126},{"type":"T_RPAREN","context":"normal","value":")","line":4,"start":126,"end":127},{"type":"T_SEMICOLON","context":"normal","value":";","line":4,"start":127,"end":128}],"errors":[]}
In which props.children
would be the array ['hello', ' world']
.
or:
1
2
3
4
5
6
7
8
9
10
|
<MyComponent>{'hello'} <strong>world</strong></MyComponent>;
React.createElement(
MyComponent,
{},
'hello',
' ',
React.createElement('strong', {}, 'world'),
);
|
{"value":"<MyComponent>{'hello'} <strong>world</strong></MyComponent>;\n\n// which is the same as...\nReact.createElement(\n MyComponent,\n {},\n 'hello',\n ' ',\n React.createElement('strong', {}, 'world'),\n);\n","tokens":[{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":1,"start":0,"end":1},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"MyComponent","line":1,"start":1,"end":12},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":1,"start":12,"end":13},{"type":"T_LCURLY","context":"normal","value":"{","line":1,"start":13,"end":14},{"type":"T_STRING","context":"normal","value":"'hello'","line":1,"start":14,"end":21},{"type":"T_RCURLY","context":"normal","value":"}","line":1,"start":21,"end":22},{"type":"T_JSX_TEXT","context":"jsxChild","value":" ","line":1,"start":22,"end":23},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":1,"start":23,"end":24},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"strong","line":1,"start":24,"end":30},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":1,"start":30,"end":31},{"type":"T_JSX_TEXT","context":"jsxChild","value":"world","line":1,"start":31,"end":36},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":1,"start":36,"end":37},{"type":"T_DIV","context":"jsxTag","value":"/","line":1,"start":37,"end":38},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"strong","line":1,"start":38,"end":44},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":1,"start":44,"end":45},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":1,"start":45,"end":46},{"type":"T_DIV","context":"jsxTag","value":"/","line":1,"start":46,"end":47},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"MyComponent","line":1,"start":47,"end":58},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":1,"start":58,"end":59},{"type":"T_SEMICOLON","context":"normal","value":";","line":1,"start":59,"end":60},{"type":"Line","context":"comment","value":"// which is the same as...","line":3,"start":62,"end":88},{"type":"T_IDENTIFIER","context":"normal","value":"React","line":4,"start":89,"end":94},{"type":"T_PERIOD","context":"normal","value":".","line":4,"start":94,"end":95},{"type":"T_IDENTIFIER","context":"normal","value":"createElement","line":4,"start":95,"end":108},{"type":"T_LPAREN","context":"normal","value":"(","line":4,"start":108,"end":109},{"type":"T_IDENTIFIER","context":"normal","value":"MyComponent","line":5,"start":112,"end":123},{"type":"T_COMMA","context":"normal","value":",","line":5,"start":123,"end":124},{"type":"T_LCURLY","context":"normal","value":"{","line":6,"start":127,"end":128},{"type":"T_RCURLY","context":"normal","value":"}","line":6,"start":128,"end":129},{"type":"T_COMMA","context":"normal","value":",","line":6,"start":129,"end":130},{"type":"T_STRING","context":"normal","value":"'hello'","line":7,"start":133,"end":140},{"type":"T_COMMA","context":"normal","value":",","line":7,"start":140,"end":141},{"type":"T_STRING","context":"normal","value":"' '","line":8,"start":144,"end":147},{"type":"T_COMMA","context":"normal","value":",","line":8,"start":147,"end":148},{"type":"T_IDENTIFIER","context":"normal","value":"React","line":9,"start":151,"end":156},{"type":"T_PERIOD","context":"normal","value":".","line":9,"start":156,"end":157},{"type":"T_IDENTIFIER","context":"normal","value":"createElement","line":9,"start":157,"end":170},{"type":"T_LPAREN","context":"normal","value":"(","line":9,"start":170,"end":171},{"type":"T_STRING","context":"normal","value":"'strong'","line":9,"start":171,"end":179},{"type":"T_COMMA","context":"normal","value":",","line":9,"start":179,"end":180},{"type":"T_LCURLY","context":"normal","value":"{","line":9,"start":181,"end":182},{"type":"T_RCURLY","context":"normal","value":"}","line":9,"start":182,"end":183},{"type":"T_COMMA","context":"normal","value":",","line":9,"start":183,"end":184},{"type":"T_STRING","context":"normal","value":"'world'","line":9,"start":185,"end":192},{"type":"T_RPAREN","context":"normal","value":")","line":9,"start":192,"end":193},{"type":"T_COMMA","context":"normal","value":",","line":9,"start":193,"end":194},{"type":"T_RPAREN","context":"normal","value":")","line":10,"start":195,"end":196},{"type":"T_SEMICOLON","context":"normal","value":";","line":10,"start":196,"end":197}],"errors":[]}
In which props.children
would be the array
['hello', ' ', <strong>world</strong>]
.
Moving on to the next case. What happens if we have a single child, but that
child is an array?
1
2
3
4
|
<MyComponent>{[1, 2]}</MyComponent>;
React.createElement(MyComponent, {}, [1, 2]);
|
{"value":"<MyComponent>{[1, 2]}</MyComponent>;\n\n// which is the same as...\nReact.createElement(MyComponent, {}, [1, 2]);\n","tokens":[{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":1,"start":0,"end":1},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"MyComponent","line":1,"start":1,"end":12},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":1,"start":12,"end":13},{"type":"T_LCURLY","context":"normal","value":"{","line":1,"start":13,"end":14},{"type":"T_LBRACKET","context":"normal","value":"[","line":1,"start":14,"end":15},{"type":"T_NUMBER","context":"normal","value":"1","line":1,"start":15,"end":16},{"type":"T_COMMA","context":"normal","value":",","line":1,"start":16,"end":17},{"type":"T_NUMBER","context":"normal","value":"2","line":1,"start":18,"end":19},{"type":"T_RBRACKET","context":"normal","value":"]","line":1,"start":19,"end":20},{"type":"T_RCURLY","context":"normal","value":"}","line":1,"start":20,"end":21},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":1,"start":21,"end":22},{"type":"T_DIV","context":"jsxTag","value":"/","line":1,"start":22,"end":23},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"MyComponent","line":1,"start":23,"end":34},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":1,"start":34,"end":35},{"type":"T_SEMICOLON","context":"normal","value":";","line":1,"start":35,"end":36},{"type":"Line","context":"comment","value":"// which is the same as...","line":3,"start":38,"end":64},{"type":"T_IDENTIFIER","context":"normal","value":"React","line":4,"start":65,"end":70},{"type":"T_PERIOD","context":"normal","value":".","line":4,"start":70,"end":71},{"type":"T_IDENTIFIER","context":"normal","value":"createElement","line":4,"start":71,"end":84},{"type":"T_LPAREN","context":"normal","value":"(","line":4,"start":84,"end":85},{"type":"T_IDENTIFIER","context":"normal","value":"MyComponent","line":4,"start":85,"end":96},{"type":"T_COMMA","context":"normal","value":",","line":4,"start":96,"end":97},{"type":"T_LCURLY","context":"normal","value":"{","line":4,"start":98,"end":99},{"type":"T_RCURLY","context":"normal","value":"}","line":4,"start":99,"end":100},{"type":"T_COMMA","context":"normal","value":",","line":4,"start":100,"end":101},{"type":"T_LBRACKET","context":"normal","value":"[","line":4,"start":102,"end":103},{"type":"T_NUMBER","context":"normal","value":"1","line":4,"start":103,"end":104},{"type":"T_COMMA","context":"normal","value":",","line":4,"start":104,"end":105},{"type":"T_NUMBER","context":"normal","value":"2","line":4,"start":106,"end":107},{"type":"T_RBRACKET","context":"normal","value":"]","line":4,"start":107,"end":108},{"type":"T_RPAREN","context":"normal","value":")","line":4,"start":108,"end":109},{"type":"T_SEMICOLON","context":"normal","value":";","line":4,"start":109,"end":110}],"errors":[]}
This follows the same rule that when you pass in a single child then
props.children
will be exactly that value. Even though [1, 2]
is an array
it is a single value and so props.children
will be exactly that value. That
is to say props.children
will be the array [1, 2]
and not an array of
arrays.
This case happens often when you use array.map()
such as in:
1
2
3
4
5
6
7
8
9
10
|
<MyComponent>
{messages.map(message => <strong>{message}</strong>)}
</MyComponent>
React.createElement(
MyComponent,
{},
messages.map(message => React.createElement('strong', {}, message)),
);
|
{"value":"<MyComponent>\n {messages.map(message => <strong>{message}</strong>)}\n</MyComponent>\n\n// which is the same as...\nReact.createElement(\n MyComponent,\n {},\n messages.map(message => React.createElement('strong', {}, message)),\n);\n","tokens":[{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":1,"start":0,"end":1},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"MyComponent","line":1,"start":1,"end":12},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":1,"start":12,"end":13},{"type":"T_JSX_TEXT","context":"jsxChild","value":"\n ","line":1,"start":13,"end":16},{"type":"T_LCURLY","context":"normal","value":"{","line":2,"start":16,"end":17},{"type":"T_IDENTIFIER","context":"normal","value":"messages","line":2,"start":17,"end":25},{"type":"T_PERIOD","context":"normal","value":".","line":2,"start":25,"end":26},{"type":"T_IDENTIFIER","context":"normal","value":"map","line":2,"start":26,"end":29},{"type":"T_LPAREN","context":"normal","value":"(","line":2,"start":29,"end":30},{"type":"T_IDENTIFIER","context":"normal","value":"message","line":2,"start":30,"end":37},{"type":"T_ARROW","context":"normal","value":"=>","line":2,"start":38,"end":40},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":2,"start":41,"end":42},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"strong","line":2,"start":42,"end":48},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":2,"start":48,"end":49},{"type":"T_LCURLY","context":"normal","value":"{","line":2,"start":49,"end":50},{"type":"T_IDENTIFIER","context":"normal","value":"message","line":2,"start":50,"end":57},{"type":"T_RCURLY","context":"normal","value":"}","line":2,"start":57,"end":58},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":2,"start":58,"end":59},{"type":"T_DIV","context":"jsxTag","value":"/","line":2,"start":59,"end":60},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"strong","line":2,"start":60,"end":66},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":2,"start":66,"end":67},{"type":"T_RPAREN","context":"normal","value":")","line":2,"start":67,"end":68},{"type":"T_RCURLY","context":"normal","value":"}","line":2,"start":68,"end":69},{"type":"T_JSX_TEXT","context":"jsxChild","value":"\n","line":2,"start":69,"end":70},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":3,"start":70,"end":71},{"type":"T_DIV","context":"jsxTag","value":"/","line":3,"start":71,"end":72},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"MyComponent","line":3,"start":72,"end":83},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":3,"start":83,"end":84},{"type":"Line","context":"comment","value":"// which is the same as...","line":5,"start":86,"end":112},{"type":"T_IDENTIFIER","context":"normal","value":"React","line":6,"start":113,"end":118},{"type":"T_PERIOD","context":"normal","value":".","line":6,"start":118,"end":119},{"type":"T_IDENTIFIER","context":"normal","value":"createElement","line":6,"start":119,"end":132},{"type":"T_LPAREN","context":"normal","value":"(","line":6,"start":132,"end":133},{"type":"T_IDENTIFIER","context":"normal","value":"MyComponent","line":7,"start":136,"end":147},{"type":"T_COMMA","context":"normal","value":",","line":7,"start":147,"end":148},{"type":"T_LCURLY","context":"normal","value":"{","line":8,"start":151,"end":152},{"type":"T_RCURLY","context":"normal","value":"}","line":8,"start":152,"end":153},{"type":"T_COMMA","context":"normal","value":",","line":8,"start":153,"end":154},{"type":"T_IDENTIFIER","context":"normal","value":"messages","line":9,"start":157,"end":165},{"type":"T_PERIOD","context":"normal","value":".","line":9,"start":165,"end":166},{"type":"T_IDENTIFIER","context":"normal","value":"map","line":9,"start":166,"end":169},{"type":"T_LPAREN","context":"normal","value":"(","line":9,"start":169,"end":170},{"type":"T_IDENTIFIER","context":"normal","value":"message","line":9,"start":170,"end":177},{"type":"T_ARROW","context":"normal","value":"=>","line":9,"start":178,"end":180},{"type":"T_IDENTIFIER","context":"normal","value":"React","line":9,"start":181,"end":186},{"type":"T_PERIOD","context":"normal","value":".","line":9,"start":186,"end":187},{"type":"T_IDENTIFIER","context":"normal","value":"createElement","line":9,"start":187,"end":200},{"type":"T_LPAREN","context":"normal","value":"(","line":9,"start":200,"end":201},{"type":"T_STRING","context":"normal","value":"'strong'","line":9,"start":201,"end":209},{"type":"T_COMMA","context":"normal","value":",","line":9,"start":209,"end":210},{"type":"T_LCURLY","context":"normal","value":"{","line":9,"start":211,"end":212},{"type":"T_RCURLY","context":"normal","value":"}","line":9,"start":212,"end":213},{"type":"T_COMMA","context":"normal","value":",","line":9,"start":213,"end":214},{"type":"T_IDENTIFIER","context":"normal","value":"message","line":9,"start":215,"end":222},{"type":"T_RPAREN","context":"normal","value":")","line":9,"start":222,"end":223},{"type":"T_RPAREN","context":"normal","value":")","line":9,"start":223,"end":224},{"type":"T_COMMA","context":"normal","value":",","line":9,"start":224,"end":225},{"type":"T_RPAREN","context":"normal","value":")","line":10,"start":226,"end":227},{"type":"T_SEMICOLON","context":"normal","value":";","line":10,"start":227,"end":228}],"errors":[]}
So a single array child is left alone, but what happens if we have multiple
children that are arrays?
1
2
3
4
|
<MyComponent>{[1, 2]}{[3, 4]}</MyComponent>;
React.createElement(MyComponent, {}, [1, 2], [3, 4]);
|
{"value":"<MyComponent>{[1, 2]}{[3, 4]}</MyComponent>;\n\n// which is the same as...\nReact.createElement(MyComponent, {}, [1, 2], [3, 4]);\n","tokens":[{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":1,"start":0,"end":1},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"MyComponent","line":1,"start":1,"end":12},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":1,"start":12,"end":13},{"type":"T_LCURLY","context":"normal","value":"{","line":1,"start":13,"end":14},{"type":"T_LBRACKET","context":"normal","value":"[","line":1,"start":14,"end":15},{"type":"T_NUMBER","context":"normal","value":"1","line":1,"start":15,"end":16},{"type":"T_COMMA","context":"normal","value":",","line":1,"start":16,"end":17},{"type":"T_NUMBER","context":"normal","value":"2","line":1,"start":18,"end":19},{"type":"T_RBRACKET","context":"normal","value":"]","line":1,"start":19,"end":20},{"type":"T_RCURLY","context":"normal","value":"}","line":1,"start":20,"end":21},{"type":"T_LCURLY","context":"normal","value":"{","line":1,"start":21,"end":22},{"type":"T_LBRACKET","context":"normal","value":"[","line":1,"start":22,"end":23},{"type":"T_NUMBER","context":"normal","value":"3","line":1,"start":23,"end":24},{"type":"T_COMMA","context":"normal","value":",","line":1,"start":24,"end":25},{"type":"T_NUMBER","context":"normal","value":"4","line":1,"start":26,"end":27},{"type":"T_RBRACKET","context":"normal","value":"]","line":1,"start":27,"end":28},{"type":"T_RCURLY","context":"normal","value":"}","line":1,"start":28,"end":29},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":1,"start":29,"end":30},{"type":"T_DIV","context":"jsxTag","value":"/","line":1,"start":30,"end":31},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"MyComponent","line":1,"start":31,"end":42},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":1,"start":42,"end":43},{"type":"T_SEMICOLON","context":"normal","value":";","line":1,"start":43,"end":44},{"type":"Line","context":"comment","value":"// which is the same as...","line":3,"start":46,"end":72},{"type":"T_IDENTIFIER","context":"normal","value":"React","line":4,"start":73,"end":78},{"type":"T_PERIOD","context":"normal","value":".","line":4,"start":78,"end":79},{"type":"T_IDENTIFIER","context":"normal","value":"createElement","line":4,"start":79,"end":92},{"type":"T_LPAREN","context":"normal","value":"(","line":4,"start":92,"end":93},{"type":"T_IDENTIFIER","context":"normal","value":"MyComponent","line":4,"start":93,"end":104},{"type":"T_COMMA","context":"normal","value":",","line":4,"start":104,"end":105},{"type":"T_LCURLY","context":"normal","value":"{","line":4,"start":106,"end":107},{"type":"T_RCURLY","context":"normal","value":"}","line":4,"start":107,"end":108},{"type":"T_COMMA","context":"normal","value":",","line":4,"start":108,"end":109},{"type":"T_LBRACKET","context":"normal","value":"[","line":4,"start":110,"end":111},{"type":"T_NUMBER","context":"normal","value":"1","line":4,"start":111,"end":112},{"type":"T_COMMA","context":"normal","value":",","line":4,"start":112,"end":113},{"type":"T_NUMBER","context":"normal","value":"2","line":4,"start":114,"end":115},{"type":"T_RBRACKET","context":"normal","value":"]","line":4,"start":115,"end":116},{"type":"T_COMMA","context":"normal","value":",","line":4,"start":116,"end":117},{"type":"T_LBRACKET","context":"normal","value":"[","line":4,"start":118,"end":119},{"type":"T_NUMBER","context":"normal","value":"3","line":4,"start":119,"end":120},{"type":"T_COMMA","context":"normal","value":",","line":4,"start":120,"end":121},{"type":"T_NUMBER","context":"normal","value":"4","line":4,"start":122,"end":123},{"type":"T_RBRACKET","context":"normal","value":"]","line":4,"start":123,"end":124},{"type":"T_RPAREN","context":"normal","value":")","line":4,"start":124,"end":125},{"type":"T_SEMICOLON","context":"normal","value":";","line":4,"start":125,"end":126}],"errors":[]}
Here props.children
will be an array of arrays. Specifically props.children
will be [[1, 2], [3, 4]]
.
The rule to remember with React children is that if you have no children then
props.children
will not be set, if you have one single child then
props.children
will be set to exactly that value, and if you have two or more
children then props.children
will be a new array of those values.
Note: Watch out for whitespace! Take the following:
<MyComponent>{42} </MyComponent>
This compiles to: React.createElement(MyComponent, {}, 42, ' ')
. (With the
spaces!) See how the spaces show up as part of the children? In this case
props.children
would be [42, ' ']
and not the number 42. However, the
following is fine:
<MyComponent>
{42}
</MyComponent>
It will compile to what you would expect:
React.createElement(MyComponent, {}, 42)
.
Newlines and indentation after newlines are stripped, but watch out for
whitespace when using a component with strict types around what children may
be.
Note: Watch out for comments! Take the following:
<MyComponent>
// some comment...
{42}
</MyComponent>
This compiles to:
React.createElement(MyComponent, {}, '// some comment...', 42)
. See how
the comment is included in the element’s children? In this case
props.children
would be ['// some comment...', 42]
which includes the
comment. To write comments in JSX use the following syntax:
<MyComponent>
{/* some comment... */}
{42}
</MyComponent>
Now let's see how you would take this intuition and type the children of various
React components.
Only allowing a specific element type as children.
Sometimes you only want a specific component as the children to your React
component. This often happens when you are building a table component which needs
specific column children components, or a tab bar which needs specific
configuration for each tab. One such tab bar component that uses this pattern is
React Native’s <TabBarIOS>
component.
React Native’s <TabBarIOS>
component only allows React element children
and those elements must have a component type of <TabBarIOS.Item>
. You are
expected to use <TabBarIOS>
like:
1
2
3
4
5
|
<TabBarIOS>
<TabBarIOS.Item>{}</TabBarIOS.Item>
<TabBarIOS.Item>{}</TabBarIOS.Item>
<TabBarIOS.Item>{}</TabBarIOS.Item>
</TabBarIOS>
|
{"value":"<TabBarIOS>\n <TabBarIOS.Item>{/* ... */}</TabBarIOS.Item>\n <TabBarIOS.Item>{/* ... */}</TabBarIOS.Item>\n <TabBarIOS.Item>{/* ... */}</TabBarIOS.Item>\n</TabBarIOS>\n","tokens":[{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":1,"start":0,"end":1},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"TabBarIOS","line":1,"start":1,"end":10},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":1,"start":10,"end":11},{"type":"T_JSX_TEXT","context":"jsxChild","value":"\n ","line":1,"start":11,"end":14},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":2,"start":14,"end":15},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"TabBarIOS","line":2,"start":15,"end":24},{"type":"T_PERIOD","context":"jsxTag","value":".","line":2,"start":24,"end":25},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"Item","line":2,"start":25,"end":29},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":2,"start":29,"end":30},{"type":"T_LCURLY","context":"normal","value":"{","line":2,"start":30,"end":31},{"type":"Block","context":"comment","value":"/* ... */","line":2,"start":31,"end":40},{"type":"T_RCURLY","context":"normal","value":"}","line":2,"start":40,"end":41},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":2,"start":41,"end":42},{"type":"T_DIV","context":"jsxTag","value":"/","line":2,"start":42,"end":43},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"TabBarIOS","line":2,"start":43,"end":52},{"type":"T_PERIOD","context":"jsxTag","value":".","line":2,"start":52,"end":53},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"Item","line":2,"start":53,"end":57},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":2,"start":57,"end":58},{"type":"T_JSX_TEXT","context":"jsxChild","value":"\n ","line":2,"start":58,"end":61},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":3,"start":61,"end":62},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"TabBarIOS","line":3,"start":62,"end":71},{"type":"T_PERIOD","context":"jsxTag","value":".","line":3,"start":71,"end":72},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"Item","line":3,"start":72,"end":76},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":3,"start":76,"end":77},{"type":"T_LCURLY","context":"normal","value":"{","line":3,"start":77,"end":78},{"type":"Block","context":"comment","value":"/* ... */","line":3,"start":78,"end":87},{"type":"T_RCURLY","context":"normal","value":"}","line":3,"start":87,"end":88},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":3,"start":88,"end":89},{"type":"T_DIV","context":"jsxTag","value":"/","line":3,"start":89,"end":90},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"TabBarIOS","line":3,"start":90,"end":99},{"type":"T_PERIOD","context":"jsxTag","value":".","line":3,"start":99,"end":100},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"Item","line":3,"start":100,"end":104},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":3,"start":104,"end":105},{"type":"T_JSX_TEXT","context":"jsxChild","value":"\n ","line":3,"start":105,"end":108},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":4,"start":108,"end":109},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"TabBarIOS","line":4,"start":109,"end":118},{"type":"T_PERIOD","context":"jsxTag","value":".","line":4,"start":118,"end":119},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"Item","line":4,"start":119,"end":123},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":4,"start":123,"end":124},{"type":"T_LCURLY","context":"normal","value":"{","line":4,"start":124,"end":125},{"type":"Block","context":"comment","value":"/* ... */","line":4,"start":125,"end":134},{"type":"T_RCURLY","context":"normal","value":"}","line":4,"start":134,"end":135},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":4,"start":135,"end":136},{"type":"T_DIV","context":"jsxTag","value":"/","line":4,"start":136,"end":137},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"TabBarIOS","line":4,"start":137,"end":146},{"type":"T_PERIOD","context":"jsxTag","value":".","line":4,"start":146,"end":147},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"Item","line":4,"start":147,"end":151},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":4,"start":151,"end":152},{"type":"T_JSX_TEXT","context":"jsxChild","value":"\n","line":4,"start":152,"end":153},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":5,"start":153,"end":154},{"type":"T_DIV","context":"jsxTag","value":"/","line":5,"start":154,"end":155},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"TabBarIOS","line":5,"start":155,"end":164},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":5,"start":164,"end":165}],"errors":[]}
You are not allowed to do the following when using <TabBarIOS>
:
1
2
3
4
5
6
7
|
<TabBarIOS>
<TabBarIOS.Item>{}</TabBarIOS.Item>
<TabBarIOS.Item>{}</TabBarIOS.Item>
<View>{}</View>
<SomeOtherComponent>{}</SomeOtherComponent>
<TabBarIOS.Item>{}</TabBarIOS.Item>
</TabBarIOS>
|
{"value":"<TabBarIOS>\n <TabBarIOS.Item>{/* ... */}</TabBarIOS.Item>\n <TabBarIOS.Item>{/* ... */}</TabBarIOS.Item>\n <View>{/* ... */}</View>\n <SomeOtherComponent>{/* ... */}</SomeOtherComponent>\n <TabBarIOS.Item>{/* ... */}</TabBarIOS.Item>\n</TabBarIOS>\n","tokens":[{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":1,"start":0,"end":1},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"TabBarIOS","line":1,"start":1,"end":10},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":1,"start":10,"end":11},{"type":"T_JSX_TEXT","context":"jsxChild","value":"\n ","line":1,"start":11,"end":14},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":2,"start":14,"end":15},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"TabBarIOS","line":2,"start":15,"end":24},{"type":"T_PERIOD","context":"jsxTag","value":".","line":2,"start":24,"end":25},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"Item","line":2,"start":25,"end":29},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":2,"start":29,"end":30},{"type":"T_LCURLY","context":"normal","value":"{","line":2,"start":30,"end":31},{"type":"Block","context":"comment","value":"/* ... */","line":2,"start":31,"end":40},{"type":"T_RCURLY","context":"normal","value":"}","line":2,"start":40,"end":41},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":2,"start":41,"end":42},{"type":"T_DIV","context":"jsxTag","value":"/","line":2,"start":42,"end":43},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"TabBarIOS","line":2,"start":43,"end":52},{"type":"T_PERIOD","context":"jsxTag","value":".","line":2,"start":52,"end":53},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"Item","line":2,"start":53,"end":57},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":2,"start":57,"end":58},{"type":"T_JSX_TEXT","context":"jsxChild","value":"\n ","line":2,"start":58,"end":61},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":3,"start":61,"end":62},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"TabBarIOS","line":3,"start":62,"end":71},{"type":"T_PERIOD","context":"jsxTag","value":".","line":3,"start":71,"end":72},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"Item","line":3,"start":72,"end":76},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":3,"start":76,"end":77},{"type":"T_LCURLY","context":"normal","value":"{","line":3,"start":77,"end":78},{"type":"Block","context":"comment","value":"/* ... */","line":3,"start":78,"end":87},{"type":"T_RCURLY","context":"normal","value":"}","line":3,"start":87,"end":88},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":3,"start":88,"end":89},{"type":"T_DIV","context":"jsxTag","value":"/","line":3,"start":89,"end":90},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"TabBarIOS","line":3,"start":90,"end":99},{"type":"T_PERIOD","context":"jsxTag","value":".","line":3,"start":99,"end":100},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"Item","line":3,"start":100,"end":104},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":3,"start":104,"end":105},{"type":"T_JSX_TEXT","context":"jsxChild","value":"\n ","line":3,"start":105,"end":108},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":4,"start":108,"end":109},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"View","line":4,"start":109,"end":113},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":4,"start":113,"end":114},{"type":"T_LCURLY","context":"normal","value":"{","line":4,"start":114,"end":115},{"type":"Block","context":"comment","value":"/* ... */","line":4,"start":115,"end":124},{"type":"T_RCURLY","context":"normal","value":"}","line":4,"start":124,"end":125},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":4,"start":125,"end":126},{"type":"T_DIV","context":"jsxTag","value":"/","line":4,"start":126,"end":127},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"View","line":4,"start":127,"end":131},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":4,"start":131,"end":132},{"type":"T_JSX_TEXT","context":"jsxChild","value":"\n ","line":4,"start":132,"end":135},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":5,"start":135,"end":136},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"SomeOtherComponent","line":5,"start":136,"end":154},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":5,"start":154,"end":155},{"type":"T_LCURLY","context":"normal","value":"{","line":5,"start":155,"end":156},{"type":"Block","context":"comment","value":"/* ... */","line":5,"start":156,"end":165},{"type":"T_RCURLY","context":"normal","value":"}","line":5,"start":165,"end":166},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":5,"start":166,"end":167},{"type":"T_DIV","context":"jsxTag","value":"/","line":5,"start":167,"end":168},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"SomeOtherComponent","line":5,"start":168,"end":186},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":5,"start":186,"end":187},{"type":"T_JSX_TEXT","context":"jsxChild","value":"\n ","line":5,"start":187,"end":190},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":6,"start":190,"end":191},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"TabBarIOS","line":6,"start":191,"end":200},{"type":"T_PERIOD","context":"jsxTag","value":".","line":6,"start":200,"end":201},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"Item","line":6,"start":201,"end":205},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":6,"start":205,"end":206},{"type":"T_LCURLY","context":"normal","value":"{","line":6,"start":206,"end":207},{"type":"Block","context":"comment","value":"/* ... */","line":6,"start":207,"end":216},{"type":"T_RCURLY","context":"normal","value":"}","line":6,"start":216,"end":217},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":6,"start":217,"end":218},{"type":"T_DIV","context":"jsxTag","value":"/","line":6,"start":218,"end":219},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"TabBarIOS","line":6,"start":219,"end":228},{"type":"T_PERIOD","context":"jsxTag","value":".","line":6,"start":228,"end":229},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"Item","line":6,"start":229,"end":233},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":6,"start":233,"end":234},{"type":"T_JSX_TEXT","context":"jsxChild","value":"\n","line":6,"start":234,"end":235},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":7,"start":235,"end":236},{"type":"T_DIV","context":"jsxTag","value":"/","line":7,"start":236,"end":237},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"TabBarIOS","line":7,"start":237,"end":246},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":7,"start":246,"end":247}],"errors":[]}
See how we added <View>
and <SomeOtherComponent>
as children to
<TabBarIOS>
? This is not allowed and <TabBarIOS>
will throw an error. How do
we make sure Flow does not allow this pattern?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
import * as React from 'react';
class TabBarIOSItem extends React.Component<{}> {
}
type Props = {
children: React.ChildrenArray<React.Element<typeof TabBarIOSItem>>,
};
class TabBarIOS extends React.Component<Props> {
static Item = TabBarIOSItem;
}
<TabBarIOS>
<TabBarIOS.Item>{}</TabBarIOS.Item>
<TabBarIOS.Item>{}</TabBarIOS.Item>
<TabBarIOS.Item>{}</TabBarIOS.Item>
</TabBarIOS>;
|
{"value":"import * as React from 'react';\n\nclass TabBarIOSItem extends React.Component<{}> {\n // implementation...\n}\n\ntype Props = {\n children: React.ChildrenArray<React.Element<typeof TabBarIOSItem>>,\n};\n\nclass TabBarIOS extends React.Component<Props> {\n static Item = TabBarIOSItem;\n // implementation...\n}\n\n<TabBarIOS>\n <TabBarIOS.Item>{/* ... */}</TabBarIOS.Item>\n <TabBarIOS.Item>{/* ... */}</TabBarIOS.Item>\n <TabBarIOS.Item>{/* ... */}</TabBarIOS.Item>\n</TabBarIOS>;\n","tokens":[{"type":"T_IMPORT","context":"normal","value":"import","line":1,"start":0,"end":6},{"type":"T_MULT","context":"normal","value":"*","line":1,"start":7,"end":8},{"type":"T_IDENTIFIER","context":"normal","value":"as","line":1,"start":9,"end":11},{"type":"T_IDENTIFIER","context":"normal","value":"React","line":1,"start":12,"end":17},{"type":"T_IDENTIFIER","context":"normal","value":"from","line":1,"start":18,"end":22},{"type":"T_STRING","context":"normal","value":"'react'","line":1,"start":23,"end":30},{"type":"T_SEMICOLON","context":"normal","value":";","line":1,"start":30,"end":31},{"type":"T_CLASS","context":"normal","value":"class","line":3,"start":33,"end":38},{"type":"T_IDENTIFIER","context":"normal","value":"TabBarIOSItem","line":3,"start":39,"end":52},{"type":"T_EXTENDS","context":"normal","value":"extends","line":3,"start":53,"end":60},{"type":"T_IDENTIFIER","context":"normal","value":"React","line":3,"start":61,"end":66},{"type":"T_PERIOD","context":"normal","value":".","line":3,"start":66,"end":67},{"type":"T_IDENTIFIER","context":"normal","value":"Component","line":3,"start":67,"end":76},{"type":"T_LESS_THAN","context":"type","value":"<","line":3,"start":76,"end":77},{"type":"T_LCURLY","context":"type","value":"{","line":3,"start":77,"end":78},{"type":"T_RCURLY","context":"type","value":"}","line":3,"start":78,"end":79},{"type":"T_GREATER_THAN","context":"type","value":">","line":3,"start":79,"end":80},{"type":"T_LCURLY","context":"normal","value":"{","line":3,"start":81,"end":82},{"type":"Line","context":"comment","value":"// implementation...","line":4,"start":85,"end":105},{"type":"T_RCURLY","context":"normal","value":"}","line":5,"start":106,"end":107},{"type":"T_TYPE","context":"normal","value":"type","line":7,"start":109,"end":113},{"type":"T_IDENTIFIER","context":"type","value":"Props","line":7,"start":114,"end":119},{"type":"T_ASSIGN","context":"type","value":"=","line":7,"start":120,"end":121},{"type":"T_LCURLY","context":"type","value":"{","line":7,"start":122,"end":123},{"type":"T_IDENTIFIER","context":"normal","value":"children","line":8,"start":126,"end":134},{"type":"T_COLON","context":"type","value":":","line":8,"start":134,"end":135},{"type":"T_IDENTIFIER","context":"type","value":"React","line":8,"start":136,"end":141},{"type":"T_PERIOD","context":"type","value":".","line":8,"start":141,"end":142},{"type":"T_IDENTIFIER","context":"type","value":"ChildrenArray","line":8,"start":142,"end":155},{"type":"T_LESS_THAN","context":"type","value":"<","line":8,"start":155,"end":156},{"type":"T_IDENTIFIER","context":"type","value":"React","line":8,"start":156,"end":161},{"type":"T_PERIOD","context":"type","value":".","line":8,"start":161,"end":162},{"type":"T_IDENTIFIER","context":"type","value":"Element","line":8,"start":162,"end":169},{"type":"T_LESS_THAN","context":"type","value":"<","line":8,"start":169,"end":170},{"type":"T_TYPEOF","context":"type","value":"typeof","line":8,"start":170,"end":176},{"type":"T_IDENTIFIER","context":"type","value":"TabBarIOSItem","line":8,"start":177,"end":190},{"type":"T_GREATER_THAN","context":"type","value":">","line":8,"start":190,"end":191},{"type":"T_GREATER_THAN","context":"type","value":">","line":8,"start":191,"end":192},{"type":"T_COMMA","context":"type","value":",","line":8,"start":192,"end":193},{"type":"T_RCURLY","context":"type","value":"}","line":9,"start":194,"end":195},{"type":"T_SEMICOLON","context":"normal","value":";","line":9,"start":195,"end":196},{"type":"T_CLASS","context":"normal","value":"class","line":11,"start":198,"end":203},{"type":"T_IDENTIFIER","context":"normal","value":"TabBarIOS","line":11,"start":204,"end":213},{"type":"T_EXTENDS","context":"normal","value":"extends","line":11,"start":214,"end":221},{"type":"T_IDENTIFIER","context":"normal","value":"React","line":11,"start":222,"end":227},{"type":"T_PERIOD","context":"normal","value":".","line":11,"start":227,"end":228},{"type":"T_IDENTIFIER","context":"normal","value":"Component","line":11,"start":228,"end":237},{"type":"T_LESS_THAN","context":"type","value":"<","line":11,"start":237,"end":238},{"type":"T_IDENTIFIER","context":"type","value":"Props","line":11,"start":238,"end":243},{"type":"T_GREATER_THAN","context":"type","value":">","line":11,"start":243,"end":244},{"type":"T_LCURLY","context":"normal","value":"{","line":11,"start":245,"end":246},{"type":"T_STATIC","context":"normal","value":"static","line":12,"start":249,"end":255},{"type":"T_IDENTIFIER","context":"normal","value":"Item","line":12,"start":256,"end":260},{"type":"T_ASSIGN","context":"normal","value":"=","line":12,"start":261,"end":262},{"type":"T_IDENTIFIER","context":"normal","value":"TabBarIOSItem","line":12,"start":263,"end":276},{"type":"T_SEMICOLON","context":"normal","value":";","line":12,"start":276,"end":277},{"type":"Line","context":"comment","value":"// implementation...","line":13,"start":280,"end":300},{"type":"T_RCURLY","context":"normal","value":"}","line":14,"start":301,"end":302},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":16,"start":304,"end":305},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"TabBarIOS","line":16,"start":305,"end":314},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":16,"start":314,"end":315},{"type":"T_JSX_TEXT","context":"jsxChild","value":"\n ","line":16,"start":315,"end":318},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":17,"start":318,"end":319},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"TabBarIOS","line":17,"start":319,"end":328},{"type":"T_PERIOD","context":"jsxTag","value":".","line":17,"start":328,"end":329},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"Item","line":17,"start":329,"end":333},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":17,"start":333,"end":334},{"type":"T_LCURLY","context":"normal","value":"{","line":17,"start":334,"end":335},{"type":"Block","context":"comment","value":"/* ... */","line":17,"start":335,"end":344},{"type":"T_RCURLY","context":"normal","value":"}","line":17,"start":344,"end":345},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":17,"start":345,"end":346},{"type":"T_DIV","context":"jsxTag","value":"/","line":17,"start":346,"end":347},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"TabBarIOS","line":17,"start":347,"end":356},{"type":"T_PERIOD","context":"jsxTag","value":".","line":17,"start":356,"end":357},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"Item","line":17,"start":357,"end":361},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":17,"start":361,"end":362},{"type":"T_JSX_TEXT","context":"jsxChild","value":"\n ","line":17,"start":362,"end":365},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":18,"start":365,"end":366},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"TabBarIOS","line":18,"start":366,"end":375},{"type":"T_PERIOD","context":"jsxTag","value":".","line":18,"start":375,"end":376},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"Item","line":18,"start":376,"end":380},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":18,"start":380,"end":381},{"type":"T_LCURLY","context":"normal","value":"{","line":18,"start":381,"end":382},{"type":"Block","context":"comment","value":"/* ... */","line":18,"start":382,"end":391},{"type":"T_RCURLY","context":"normal","value":"}","line":18,"start":391,"end":392},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":18,"start":392,"end":393},{"type":"T_DIV","context":"jsxTag","value":"/","line":18,"start":393,"end":394},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"TabBarIOS","line":18,"start":394,"end":403},{"type":"T_PERIOD","context":"jsxTag","value":".","line":18,"start":403,"end":404},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"Item","line":18,"start":404,"end":408},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":18,"start":408,"end":409},{"type":"T_JSX_TEXT","context":"jsxChild","value":"\n ","line":18,"start":409,"end":412},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":19,"start":412,"end":413},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"TabBarIOS","line":19,"start":413,"end":422},{"type":"T_PERIOD","context":"jsxTag","value":".","line":19,"start":422,"end":423},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"Item","line":19,"start":423,"end":427},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":19,"start":427,"end":428},{"type":"T_LCURLY","context":"normal","value":"{","line":19,"start":428,"end":429},{"type":"Block","context":"comment","value":"/* ... */","line":19,"start":429,"end":438},{"type":"T_RCURLY","context":"normal","value":"}","line":19,"start":438,"end":439},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":19,"start":439,"end":440},{"type":"T_DIV","context":"jsxTag","value":"/","line":19,"start":440,"end":441},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"TabBarIOS","line":19,"start":441,"end":450},{"type":"T_PERIOD","context":"jsxTag","value":".","line":19,"start":450,"end":451},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"Item","line":19,"start":451,"end":455},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":19,"start":455,"end":456},{"type":"T_JSX_TEXT","context":"jsxChild","value":"\n","line":19,"start":456,"end":457},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":20,"start":457,"end":458},{"type":"T_DIV","context":"jsxTag","value":"/","line":20,"start":458,"end":459},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"TabBarIOS","line":20,"start":459,"end":468},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":20,"start":468,"end":469},{"type":"T_SEMICOLON","context":"normal","value":";","line":20,"start":469,"end":470}],"errors":[]}
We set the type of props to
React.ChildrenArray<React.Element<typeof TabBarIOSItem>>
which will guarantee
that <TabBarIOS>
must only have children that are TabBarIOS.Item
React
elements.
Our types reference has more information about both
React.ChildrenArray<T>
and
React.Element<typeof Component>
.
Note: If you want methods like map()
and forEach()
or to handle a
React.ChildrenArray<T>
as a normal
JavaScript array then React provides the React.Children
API to do just
this. It has functions like React.Children.toArray(props.children)
that you
can use to treat your React.ChildrenArray<T>
as a flat array.
Enforcing that a component only gets a single child.
Sometimes you want to enforce that your component will only receive a single
child. You could use React.Children.only()
function to enforce this
constraint, but you could also enforce this in Flow. To do this, instead of
wrapping the type for your children in
React.ChildrenArray<T>
, specify a single element argument, like so:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
import * as React from 'react';
type Props = {
children: React.Element<any>,
};
function MyComponent(props: Props) {
}
<MyComponent />;
<MyComponent>
<div />
<div />
<div />
</MyComponent>;
<MyComponent>
<div />
</MyComponent>;
|
{"value":"import * as React from 'react';\n\ntype Props = {\n children: React.Element<any>,\n};\n\nfunction MyComponent(props: Props) {\n // implementation...\n}\n\n// Not allowed! You must have children.\n<MyComponent />;\n\n// Not ok! We have multiple element children.\n<MyComponent>\n <div />\n <div />\n <div />\n</MyComponent>;\n\n// This is ok. We have a single element child.\n<MyComponent>\n <div />\n</MyComponent>;\n","tokens":[{"type":"T_IMPORT","context":"normal","value":"import","line":1,"start":0,"end":6},{"type":"T_MULT","context":"normal","value":"*","line":1,"start":7,"end":8},{"type":"T_IDENTIFIER","context":"normal","value":"as","line":1,"start":9,"end":11},{"type":"T_IDENTIFIER","context":"normal","value":"React","line":1,"start":12,"end":17},{"type":"T_IDENTIFIER","context":"normal","value":"from","line":1,"start":18,"end":22},{"type":"T_STRING","context":"normal","value":"'react'","line":1,"start":23,"end":30},{"type":"T_SEMICOLON","context":"normal","value":";","line":1,"start":30,"end":31},{"type":"T_TYPE","context":"normal","value":"type","line":3,"start":33,"end":37},{"type":"T_IDENTIFIER","context":"type","value":"Props","line":3,"start":38,"end":43},{"type":"T_ASSIGN","context":"type","value":"=","line":3,"start":44,"end":45},{"type":"T_LCURLY","context":"type","value":"{","line":3,"start":46,"end":47},{"type":"T_IDENTIFIER","context":"normal","value":"children","line":4,"start":50,"end":58},{"type":"T_COLON","context":"type","value":":","line":4,"start":58,"end":59},{"type":"T_IDENTIFIER","context":"type","value":"React","line":4,"start":60,"end":65},{"type":"T_PERIOD","context":"type","value":".","line":4,"start":65,"end":66},{"type":"T_IDENTIFIER","context":"type","value":"Element","line":4,"start":66,"end":73},{"type":"T_LESS_THAN","context":"type","value":"<","line":4,"start":73,"end":74},{"type":"T_ANY_TYPE","context":"type","value":"any","line":4,"start":74,"end":77},{"type":"T_GREATER_THAN","context":"type","value":">","line":4,"start":77,"end":78},{"type":"T_COMMA","context":"type","value":",","line":4,"start":78,"end":79},{"type":"T_RCURLY","context":"type","value":"}","line":5,"start":80,"end":81},{"type":"T_SEMICOLON","context":"normal","value":";","line":5,"start":81,"end":82},{"type":"T_FUNCTION","context":"normal","value":"function","line":7,"start":84,"end":92},{"type":"T_IDENTIFIER","context":"normal","value":"MyComponent","line":7,"start":93,"end":104},{"type":"T_LPAREN","context":"normal","value":"(","line":7,"start":104,"end":105},{"type":"T_IDENTIFIER","context":"normal","value":"props","line":7,"start":105,"end":110},{"type":"T_COLON","context":"type","value":":","line":7,"start":110,"end":111},{"type":"T_IDENTIFIER","context":"type","value":"Props","line":7,"start":112,"end":117},{"type":"T_RPAREN","context":"normal","value":")","line":7,"start":117,"end":118},{"type":"T_LCURLY","context":"normal","value":"{","line":7,"start":119,"end":120},{"type":"Line","context":"comment","value":"// implementation...","line":8,"start":123,"end":143},{"type":"T_RCURLY","context":"normal","value":"}","line":9,"start":144,"end":145},{"type":"Line","context":"comment","value":"// Not allowed! You must have children.","line":11,"start":147,"end":186},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":12,"start":187,"end":188},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"MyComponent","line":12,"start":188,"end":199},{"type":"T_DIV","context":"jsxTag","value":"/","line":12,"start":200,"end":201},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":12,"start":201,"end":202},{"type":"T_SEMICOLON","context":"normal","value":";","line":12,"start":202,"end":203},{"type":"Line","context":"comment","value":"// Not ok! We have multiple element children.","line":14,"start":205,"end":250},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":15,"start":251,"end":252},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"MyComponent","line":15,"start":252,"end":263},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":15,"start":263,"end":264},{"type":"T_JSX_TEXT","context":"jsxChild","value":"\n ","line":15,"start":264,"end":267},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":16,"start":267,"end":268},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"div","line":16,"start":268,"end":271},{"type":"T_DIV","context":"jsxTag","value":"/","line":16,"start":272,"end":273},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":16,"start":273,"end":274},{"type":"T_JSX_TEXT","context":"jsxChild","value":"\n ","line":16,"start":274,"end":277},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":17,"start":277,"end":278},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"div","line":17,"start":278,"end":281},{"type":"T_DIV","context":"jsxTag","value":"/","line":17,"start":282,"end":283},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":17,"start":283,"end":284},{"type":"T_JSX_TEXT","context":"jsxChild","value":"\n ","line":17,"start":284,"end":287},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":18,"start":287,"end":288},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"div","line":18,"start":288,"end":291},{"type":"T_DIV","context":"jsxTag","value":"/","line":18,"start":292,"end":293},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":18,"start":293,"end":294},{"type":"T_JSX_TEXT","context":"jsxChild","value":"\n","line":18,"start":294,"end":295},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":19,"start":295,"end":296},{"type":"T_DIV","context":"jsxTag","value":"/","line":19,"start":296,"end":297},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"MyComponent","line":19,"start":297,"end":308},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":19,"start":308,"end":309},{"type":"T_SEMICOLON","context":"normal","value":";","line":19,"start":309,"end":310},{"type":"Line","context":"comment","value":"// This is ok. We have a single element child.","line":21,"start":312,"end":358},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":22,"start":359,"end":360},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"MyComponent","line":22,"start":360,"end":371},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":22,"start":371,"end":372},{"type":"T_JSX_TEXT","context":"jsxChild","value":"\n ","line":22,"start":372,"end":375},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":23,"start":375,"end":376},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"div","line":23,"start":376,"end":379},{"type":"T_DIV","context":"jsxTag","value":"/","line":23,"start":380,"end":381},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":23,"start":381,"end":382},{"type":"T_JSX_TEXT","context":"jsxChild","value":"\n","line":23,"start":382,"end":383},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":24,"start":383,"end":384},{"type":"T_DIV","context":"jsxTag","value":"/","line":24,"start":384,"end":385},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"MyComponent","line":24,"start":385,"end":396},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":24,"start":396,"end":397},{"type":"T_SEMICOLON","context":"normal","value":";","line":24,"start":397,"end":398}],"errors":[]}
Typing function children or other exotic children types.
React allows you to pass any value as the children of a React component. There
are some creative uses of this capability such as using a function for children
which could look like this:
1
2
3
4
5
|
<MyComponent>
{data => (
<div>{data.foo}</div>
)}
</MyComponent>
|
{"value":"<MyComponent>\n {data => (\n <div>{data.foo}</div>\n )}\n</MyComponent>\n","tokens":[{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":1,"start":0,"end":1},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"MyComponent","line":1,"start":1,"end":12},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":1,"start":12,"end":13},{"type":"T_JSX_TEXT","context":"jsxChild","value":"\n ","line":1,"start":13,"end":16},{"type":"T_LCURLY","context":"normal","value":"{","line":2,"start":16,"end":17},{"type":"T_IDENTIFIER","context":"normal","value":"data","line":2,"start":17,"end":21},{"type":"T_ARROW","context":"normal","value":"=>","line":2,"start":22,"end":24},{"type":"T_LPAREN","context":"normal","value":"(","line":2,"start":25,"end":26},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":3,"start":31,"end":32},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"div","line":3,"start":32,"end":35},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":3,"start":35,"end":36},{"type":"T_LCURLY","context":"normal","value":"{","line":3,"start":36,"end":37},{"type":"T_IDENTIFIER","context":"normal","value":"data","line":3,"start":37,"end":41},{"type":"T_PERIOD","context":"normal","value":".","line":3,"start":41,"end":42},{"type":"T_IDENTIFIER","context":"normal","value":"foo","line":3,"start":42,"end":45},{"type":"T_RCURLY","context":"normal","value":"}","line":3,"start":45,"end":46},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":3,"start":46,"end":47},{"type":"T_DIV","context":"jsxTag","value":"/","line":3,"start":47,"end":48},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"div","line":3,"start":48,"end":51},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":3,"start":51,"end":52},{"type":"T_RPAREN","context":"normal","value":")","line":4,"start":55,"end":56},{"type":"T_RCURLY","context":"normal","value":"}","line":4,"start":56,"end":57},{"type":"T_JSX_TEXT","context":"jsxChild","value":"\n","line":4,"start":57,"end":58},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":5,"start":58,"end":59},{"type":"T_DIV","context":"jsxTag","value":"/","line":5,"start":59,"end":60},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"MyComponent","line":5,"start":60,"end":71},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":5,"start":71,"end":72}],"errors":[]}
react-router
version 4 asks for a function as the children to its <Route>
component. You would provide a function as the children to react-router
like this:
1
2
3
4
5
6
7
|
<Route path={to}>
{({ match }) => (
<li className={match ? 'active' : ''}>
<Link to={to} {...rest}/>
</li>
)}
</Route>
|
{"value":"<Route path={to}>\n {({ match }) => (\n <li className={match ? 'active' : ''}>\n <Link to={to} {...rest}/>\n </li>\n )}\n</Route>\n","tokens":[{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":1,"start":0,"end":1},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"Route","line":1,"start":1,"end":6},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"path","line":1,"start":7,"end":11},{"type":"T_ASSIGN","context":"jsxTag","value":"=","line":1,"start":11,"end":12},{"type":"T_LCURLY","context":"normal","value":"{","line":1,"start":12,"end":13},{"type":"T_IDENTIFIER","context":"normal","value":"to","line":1,"start":13,"end":15},{"type":"T_RCURLY","context":"normal","value":"}","line":1,"start":15,"end":16},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":1,"start":16,"end":17},{"type":"T_JSX_TEXT","context":"jsxChild","value":"\n ","line":1,"start":17,"end":20},{"type":"T_LCURLY","context":"normal","value":"{","line":2,"start":20,"end":21},{"type":"T_LPAREN","context":"normal","value":"(","line":2,"start":21,"end":22},{"type":"T_LCURLY","context":"normal","value":"{","line":2,"start":22,"end":23},{"type":"T_IDENTIFIER","context":"normal","value":"match","line":2,"start":24,"end":29},{"type":"T_RCURLY","context":"normal","value":"}","line":2,"start":30,"end":31},{"type":"T_RPAREN","context":"normal","value":")","line":2,"start":31,"end":32},{"type":"T_ARROW","context":"normal","value":"=>","line":2,"start":33,"end":35},{"type":"T_LPAREN","context":"normal","value":"(","line":2,"start":36,"end":37},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":3,"start":42,"end":43},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"li","line":3,"start":43,"end":45},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"className","line":3,"start":46,"end":55},{"type":"T_ASSIGN","context":"jsxTag","value":"=","line":3,"start":55,"end":56},{"type":"T_LCURLY","context":"normal","value":"{","line":3,"start":56,"end":57},{"type":"T_IDENTIFIER","context":"normal","value":"match","line":3,"start":57,"end":62},{"type":"T_PLING","context":"normal","value":"?","line":3,"start":63,"end":64},{"type":"T_STRING","context":"normal","value":"'active'","line":3,"start":65,"end":73},{"type":"T_COLON","context":"normal","value":":","line":3,"start":74,"end":75},{"type":"T_STRING","context":"normal","value":"''","line":3,"start":76,"end":78},{"type":"T_RCURLY","context":"normal","value":"}","line":3,"start":78,"end":79},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":3,"start":79,"end":80},{"type":"T_JSX_TEXT","context":"jsxChild","value":"\n ","line":3,"start":80,"end":87},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":4,"start":87,"end":88},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"Link","line":4,"start":88,"end":92},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"to","line":4,"start":93,"end":95},{"type":"T_ASSIGN","context":"jsxTag","value":"=","line":4,"start":95,"end":96},{"type":"T_LCURLY","context":"normal","value":"{","line":4,"start":96,"end":97},{"type":"T_IDENTIFIER","context":"normal","value":"to","line":4,"start":97,"end":99},{"type":"T_RCURLY","context":"normal","value":"}","line":4,"start":99,"end":100},{"type":"T_LCURLY","context":"normal","value":"{","line":4,"start":101,"end":102},{"type":"T_ELLIPSIS","context":"normal","value":"...","line":4,"start":102,"end":105},{"type":"T_IDENTIFIER","context":"normal","value":"rest","line":4,"start":105,"end":109},{"type":"T_RCURLY","context":"normal","value":"}","line":4,"start":109,"end":110},{"type":"T_DIV","context":"jsxTag","value":"/","line":4,"start":110,"end":111},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":4,"start":111,"end":112},{"type":"T_JSX_TEXT","context":"jsxChild","value":"\n ","line":4,"start":112,"end":117},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":5,"start":117,"end":118},{"type":"T_DIV","context":"jsxTag","value":"/","line":5,"start":118,"end":119},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"li","line":5,"start":119,"end":121},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":5,"start":121,"end":122},{"type":"T_RPAREN","context":"normal","value":")","line":6,"start":125,"end":126},{"type":"T_RCURLY","context":"normal","value":"}","line":6,"start":126,"end":127},{"type":"T_JSX_TEXT","context":"jsxChild","value":"\n","line":6,"start":127,"end":128},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":7,"start":128,"end":129},{"type":"T_DIV","context":"jsxTag","value":"/","line":7,"start":129,"end":130},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"Route","line":7,"start":130,"end":135},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":7,"start":135,"end":136}],"errors":[]}
(Example adapted from the react-router
documentation.)
Here is how you would type the <Route>
component in Flow:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
import * as React from 'react';
type Props = {
children: (data: { match: boolean }) => React.Node,
path: string,
};
class Route extends React.Component<Props> {
}
<Route path={to}>
{({ match }) => (
<li className={match ? 'active' : ''}>
<Link to={to} {...rest}/>
</li>
)}
</Route>;
|
{"value":"import * as React from 'react';\n\ntype Props = {\n children: (data: { match: boolean }) => React.Node,\n path: string,\n // other props...\n};\n\nclass Route extends React.Component<Props> {\n // implementation...\n}\n\n<Route path={to}>\n {({ match }) => (\n <li className={match ? 'active' : ''}>\n <Link to={to} {...rest}/>\n </li>\n )}\n</Route>;\n","tokens":[{"type":"T_IMPORT","context":"normal","value":"import","line":1,"start":0,"end":6},{"type":"T_MULT","context":"normal","value":"*","line":1,"start":7,"end":8},{"type":"T_IDENTIFIER","context":"normal","value":"as","line":1,"start":9,"end":11},{"type":"T_IDENTIFIER","context":"normal","value":"React","line":1,"start":12,"end":17},{"type":"T_IDENTIFIER","context":"normal","value":"from","line":1,"start":18,"end":22},{"type":"T_STRING","context":"normal","value":"'react'","line":1,"start":23,"end":30},{"type":"T_SEMICOLON","context":"normal","value":";","line":1,"start":30,"end":31},{"type":"T_TYPE","context":"normal","value":"type","line":3,"start":33,"end":37},{"type":"T_IDENTIFIER","context":"type","value":"Props","line":3,"start":38,"end":43},{"type":"T_ASSIGN","context":"type","value":"=","line":3,"start":44,"end":45},{"type":"T_LCURLY","context":"type","value":"{","line":3,"start":46,"end":47},{"type":"T_IDENTIFIER","context":"normal","value":"children","line":4,"start":50,"end":58},{"type":"T_COLON","context":"type","value":":","line":4,"start":58,"end":59},{"type":"T_LPAREN","context":"type","value":"(","line":4,"start":60,"end":61},{"type":"T_IDENTIFIER","context":"normal","value":"data","line":4,"start":61,"end":65},{"type":"T_COLON","context":"type","value":":","line":4,"start":65,"end":66},{"type":"T_LCURLY","context":"type","value":"{","line":4,"start":67,"end":68},{"type":"T_IDENTIFIER","context":"normal","value":"match","line":4,"start":69,"end":74},{"type":"T_COLON","context":"type","value":":","line":4,"start":74,"end":75},{"type":"T_BOOLEAN_TYPE","context":"type","value":"boolean","line":4,"start":76,"end":83},{"type":"T_RCURLY","context":"type","value":"}","line":4,"start":84,"end":85},{"type":"T_RPAREN","context":"type","value":")","line":4,"start":85,"end":86},{"type":"T_ARROW","context":"type","value":"=>","line":4,"start":87,"end":89},{"type":"T_IDENTIFIER","context":"type","value":"React","line":4,"start":90,"end":95},{"type":"T_PERIOD","context":"type","value":".","line":4,"start":95,"end":96},{"type":"T_IDENTIFIER","context":"type","value":"Node","line":4,"start":96,"end":100},{"type":"T_COMMA","context":"type","value":",","line":4,"start":100,"end":101},{"type":"T_IDENTIFIER","context":"normal","value":"path","line":5,"start":104,"end":108},{"type":"T_COLON","context":"type","value":":","line":5,"start":108,"end":109},{"type":"T_STRING_TYPE","context":"type","value":"string","line":5,"start":110,"end":116},{"type":"T_COMMA","context":"type","value":",","line":5,"start":116,"end":117},{"type":"Line","context":"comment","value":"// other props...","line":6,"start":120,"end":137},{"type":"T_RCURLY","context":"type","value":"}","line":7,"start":138,"end":139},{"type":"T_SEMICOLON","context":"normal","value":";","line":7,"start":139,"end":140},{"type":"T_CLASS","context":"normal","value":"class","line":9,"start":142,"end":147},{"type":"T_IDENTIFIER","context":"normal","value":"Route","line":9,"start":148,"end":153},{"type":"T_EXTENDS","context":"normal","value":"extends","line":9,"start":154,"end":161},{"type":"T_IDENTIFIER","context":"normal","value":"React","line":9,"start":162,"end":167},{"type":"T_PERIOD","context":"normal","value":".","line":9,"start":167,"end":168},{"type":"T_IDENTIFIER","context":"normal","value":"Component","line":9,"start":168,"end":177},{"type":"T_LESS_THAN","context":"type","value":"<","line":9,"start":177,"end":178},{"type":"T_IDENTIFIER","context":"type","value":"Props","line":9,"start":178,"end":183},{"type":"T_GREATER_THAN","context":"type","value":">","line":9,"start":183,"end":184},{"type":"T_LCURLY","context":"normal","value":"{","line":9,"start":185,"end":186},{"type":"Line","context":"comment","value":"// implementation...","line":10,"start":189,"end":209},{"type":"T_RCURLY","context":"normal","value":"}","line":11,"start":210,"end":211},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":13,"start":213,"end":214},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"Route","line":13,"start":214,"end":219},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"path","line":13,"start":220,"end":224},{"type":"T_ASSIGN","context":"jsxTag","value":"=","line":13,"start":224,"end":225},{"type":"T_LCURLY","context":"normal","value":"{","line":13,"start":225,"end":226},{"type":"T_IDENTIFIER","context":"normal","value":"to","line":13,"start":226,"end":228},{"type":"T_RCURLY","context":"normal","value":"}","line":13,"start":228,"end":229},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":13,"start":229,"end":230},{"type":"T_JSX_TEXT","context":"jsxChild","value":"\n ","line":13,"start":230,"end":233},{"type":"T_LCURLY","context":"normal","value":"{","line":14,"start":233,"end":234},{"type":"T_LPAREN","context":"normal","value":"(","line":14,"start":234,"end":235},{"type":"T_LCURLY","context":"normal","value":"{","line":14,"start":235,"end":236},{"type":"T_IDENTIFIER","context":"normal","value":"match","line":14,"start":237,"end":242},{"type":"T_RCURLY","context":"normal","value":"}","line":14,"start":243,"end":244},{"type":"T_RPAREN","context":"normal","value":")","line":14,"start":244,"end":245},{"type":"T_ARROW","context":"normal","value":"=>","line":14,"start":246,"end":248},{"type":"T_LPAREN","context":"normal","value":"(","line":14,"start":249,"end":250},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":15,"start":255,"end":256},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"li","line":15,"start":256,"end":258},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"className","line":15,"start":259,"end":268},{"type":"T_ASSIGN","context":"jsxTag","value":"=","line":15,"start":268,"end":269},{"type":"T_LCURLY","context":"normal","value":"{","line":15,"start":269,"end":270},{"type":"T_IDENTIFIER","context":"normal","value":"match","line":15,"start":270,"end":275},{"type":"T_PLING","context":"normal","value":"?","line":15,"start":276,"end":277},{"type":"T_STRING","context":"normal","value":"'active'","line":15,"start":278,"end":286},{"type":"T_COLON","context":"normal","value":":","line":15,"start":287,"end":288},{"type":"T_STRING","context":"normal","value":"''","line":15,"start":289,"end":291},{"type":"T_RCURLY","context":"normal","value":"}","line":15,"start":291,"end":292},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":15,"start":292,"end":293},{"type":"T_JSX_TEXT","context":"jsxChild","value":"\n ","line":15,"start":293,"end":300},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":16,"start":300,"end":301},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"Link","line":16,"start":301,"end":305},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"to","line":16,"start":306,"end":308},{"type":"T_ASSIGN","context":"jsxTag","value":"=","line":16,"start":308,"end":309},{"type":"T_LCURLY","context":"normal","value":"{","line":16,"start":309,"end":310},{"type":"T_IDENTIFIER","context":"normal","value":"to","line":16,"start":310,"end":312},{"type":"T_RCURLY","context":"normal","value":"}","line":16,"start":312,"end":313},{"type":"T_LCURLY","context":"normal","value":"{","line":16,"start":314,"end":315},{"type":"T_ELLIPSIS","context":"normal","value":"...","line":16,"start":315,"end":318},{"type":"T_IDENTIFIER","context":"normal","value":"rest","line":16,"start":318,"end":322},{"type":"T_RCURLY","context":"normal","value":"}","line":16,"start":322,"end":323},{"type":"T_DIV","context":"jsxTag","value":"/","line":16,"start":323,"end":324},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":16,"start":324,"end":325},{"type":"T_JSX_TEXT","context":"jsxChild","value":"\n ","line":16,"start":325,"end":330},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":17,"start":330,"end":331},{"type":"T_DIV","context":"jsxTag","value":"/","line":17,"start":331,"end":332},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"li","line":17,"start":332,"end":334},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":17,"start":334,"end":335},{"type":"T_RPAREN","context":"normal","value":")","line":18,"start":338,"end":339},{"type":"T_RCURLY","context":"normal","value":"}","line":18,"start":339,"end":340},{"type":"T_JSX_TEXT","context":"jsxChild","value":"\n","line":18,"start":340,"end":341},{"type":"T_LESS_THAN","context":"jsxTag","value":"<","line":19,"start":341,"end":342},{"type":"T_DIV","context":"jsxTag","value":"/","line":19,"start":342,"end":343},{"type":"T_JSX_IDENTIFIER","context":"jsxTag","value":"Route","line":19,"start":343,"end":348},{"type":"T_GREATER_THAN","context":"jsxTag","value":">","line":19,"start":348,"end":349},{"type":"T_SEMICOLON","context":"normal","value":";","line":19,"start":349,"end":350}],"errors":[]}
The type for children
is a function that takes in some object type and returns
a React.Node
which is the type for any value
that can be rendered by React. A children
function does not need to return
React.Node
. It could return any type, but in this
case react-router
wants to render the result returned by the children
function.
This pattern is also not limited to function children. You could also pass in
arbitrary object or class types.
Using React.Node
but without some primitive types like strings.
React.Node
is the general type for children, but
sometimes you might want to use React.Node
while
excluding some primitives like strings and numbers. The React Native <View>
component does this, for example.
The React Native <View>
component will allow any primitive value or any
React element as its children. However, <View>
does not allow strings or
numbers as children! You could use React.Node
as
the children type for <View>
, however React.Node
includes strings which we don’t want for <View>
. So we need to create our own
type.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
import * as React from 'react';
type ReactNodeWithoutStrings = React.ChildrenArray<
| void
| null
| boolean
| React.Element<any>
>;
type Props = {
children?: ReactNodeWithoutStrings,
};
class View extends React.Component<Props> {
}
|
{"value":"import * as React from 'react';\n\ntype ReactNodeWithoutStrings = React.ChildrenArray<\n | void\n | null\n | boolean\n | React.Element<any>\n>;\n\ntype Props = {\n children?: ReactNodeWithoutStrings,\n // other props...\n};\n\nclass View extends React.Component<Props> {\n // implementation...\n}\n","tokens":[{"type":"T_IMPORT","context":"normal","value":"import","line":1,"start":0,"end":6},{"type":"T_MULT","context":"normal","value":"*","line":1,"start":7,"end":8},{"type":"T_IDENTIFIER","context":"normal","value":"as","line":1,"start":9,"end":11},{"type":"T_IDENTIFIER","context":"normal","value":"React","line":1,"start":12,"end":17},{"type":"T_IDENTIFIER","context":"normal","value":"from","line":1,"start":18,"end":22},{"type":"T_STRING","context":"normal","value":"'react'","line":1,"start":23,"end":30},{"type":"T_SEMICOLON","context":"normal","value":";","line":1,"start":30,"end":31},{"type":"T_TYPE","context":"normal","value":"type","line":3,"start":33,"end":37},{"type":"T_IDENTIFIER","context":"type","value":"ReactNodeWithoutStrings","line":3,"start":38,"end":61},{"type":"T_ASSIGN","context":"type","value":"=","line":3,"start":62,"end":63},{"type":"T_IDENTIFIER","context":"type","value":"React","line":3,"start":64,"end":69},{"type":"T_PERIOD","context":"type","value":".","line":3,"start":69,"end":70},{"type":"T_IDENTIFIER","context":"type","value":"ChildrenArray","line":3,"start":70,"end":83},{"type":"T_LESS_THAN","context":"type","value":"<","line":3,"start":83,"end":84},{"type":"T_BIT_OR","context":"type","value":"|","line":4,"start":87,"end":88},{"type":"T_VOID_TYPE","context":"type","value":"void","line":4,"start":89,"end":93},{"type":"T_BIT_OR","context":"type","value":"|","line":5,"start":96,"end":97},{"type":"T_NULL","context":"type","value":"null","line":5,"start":98,"end":102},{"type":"T_BIT_OR","context":"type","value":"|","line":6,"start":105,"end":106},{"type":"T_BOOLEAN_TYPE","context":"type","value":"boolean","line":6,"start":107,"end":114},{"type":"T_BIT_OR","context":"type","value":"|","line":7,"start":117,"end":118},{"type":"T_IDENTIFIER","context":"type","value":"React","line":7,"start":119,"end":124},{"type":"T_PERIOD","context":"type","value":".","line":7,"start":124,"end":125},{"type":"T_IDENTIFIER","context":"type","value":"Element","line":7,"start":125,"end":132},{"type":"T_LESS_THAN","context":"type","value":"<","line":7,"start":132,"end":133},{"type":"T_ANY_TYPE","context":"type","value":"any","line":7,"start":133,"end":136},{"type":"T_GREATER_THAN","context":"type","value":">","line":7,"start":136,"end":137},{"type":"T_GREATER_THAN","context":"type","value":">","line":8,"start":138,"end":139},{"type":"T_SEMICOLON","context":"normal","value":";","line":8,"start":139,"end":140},{"type":"T_TYPE","context":"normal","value":"type","line":10,"start":142,"end":146},{"type":"T_IDENTIFIER","context":"type","value":"Props","line":10,"start":147,"end":152},{"type":"T_ASSIGN","context":"type","value":"=","line":10,"start":153,"end":154},{"type":"T_LCURLY","context":"type","value":"{","line":10,"start":155,"end":156},{"type":"T_IDENTIFIER","context":"normal","value":"children","line":11,"start":159,"end":167},{"type":"T_PLING","context":"type","value":"?","line":11,"start":167,"end":168},{"type":"T_COLON","context":"type","value":":","line":11,"start":168,"end":169},{"type":"T_IDENTIFIER","context":"type","value":"ReactNodeWithoutStrings","line":11,"start":170,"end":193},{"type":"T_COMMA","context":"type","value":",","line":11,"start":193,"end":194},{"type":"Line","context":"comment","value":"// other props...","line":12,"start":197,"end":214},{"type":"T_RCURLY","context":"type","value":"}","line":13,"start":215,"end":216},{"type":"T_SEMICOLON","context":"normal","value":";","line":13,"start":216,"end":217},{"type":"T_CLASS","context":"normal","value":"class","line":15,"start":219,"end":224},{"type":"T_IDENTIFIER","context":"normal","value":"View","line":15,"start":225,"end":229},{"type":"T_EXTENDS","context":"normal","value":"extends","line":15,"start":230,"end":237},{"type":"T_IDENTIFIER","context":"normal","value":"React","line":15,"start":238,"end":243},{"type":"T_PERIOD","context":"normal","value":".","line":15,"start":243,"end":244},{"type":"T_IDENTIFIER","context":"normal","value":"Component","line":15,"start":244,"end":253},{"type":"T_LESS_THAN","context":"type","value":"<","line":15,"start":253,"end":254},{"type":"T_IDENTIFIER","context":"type","value":"Props","line":15,"start":254,"end":259},{"type":"T_GREATER_THAN","context":"type","value":">","line":15,"start":259,"end":260},{"type":"T_LCURLY","context":"normal","value":"{","line":15,"start":261,"end":262},{"type":"Line","context":"comment","value":"// implementation...","line":16,"start":265,"end":285},{"type":"T_RCURLY","context":"normal","value":"}","line":17,"start":286,"end":287}],"errors":[]}
React.ChildrenArray<T>
is a type that
models React nested array data structure for children. ReactNodeWithoutStrings
uses React.ChildrenArray<T>
to be an
arbitrarily nested array of null, boolean, or React elements.
React.Element<typeof Component>
is the type of
a React element like <div/>
or <MyComponent/>
. Notably elements are not the
same as components!
Note: If you want methods like map()
and forEach()
or to handle a
React.ChildrenArray<T>
as a normal
JavaScript array then React provides the React.Children
API to do just
this. It has functions like React.Children.toArray(props.children)
that you
can use to treat your React.ChildrenArray<T>
as a flat array.