0% completed
Nesting Elements in JSX
On This Page
Wrapping Elements in a View
How Nesting Forms a Tree
Grouping Without an Extra View: Fragments
Nesting Text Inside Text
Return two tags side by side from a component, and the build stops before the application starts:
function CardHeader() { return ( <Text>Sara</Text> <Text>4 of 5 correct</Text> ); }
Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...</>?
The cause is what these tags become. Each tag compiles to one jsx call, and a JavaScript function can return only one value. Two calls side by side after return are not valid JavaScript, in the same way that return 1 2; is not valid. The message itself suggests one of the two usual solutions, and both of them put the tags inside a single parent.
Wrapping Elements in a View
The direct solution is to nest both Text tags inside a View:
function CardHeader() { return ( <View> <Text>Sara</Text> <Text>4 of 5 correct</Text> </View> ); }
Now there is one outer tag, so the function returns one jsx call, and the two Text calls become its children. The CardHeader examples in this lesson show only the function, so a file that uses them also needs import { Text, View } from 'react-native'; at the top.
The rule applies wherever JSX appears as one value, so each branch of a conditional must also produce a single parent. A component can also return an array of elements, but each element then needs a key, which the Managing Lists chapter explains.
How Nesting Forms a Tree
Nesting is how you build a whole screen, because an element inside another element becomes its child. Here is the profile card with a header and a row of two statistics:
import { Text, View } from 'react-native'; export default function ProfileCard() { return ( <View style={{ padding: 16, backgroundColor: '#eef6f6' }}> <Text style={{ fontSize: 24 }}>Sara</Text> <Text>4 of 5 correct</Text> <View style={{ flexDirection: 'row' }}> <Text>Quizzes: 3</Text> <Text>Streak: 7</Text> </View> </View> ); }
The indentation in the code matches the tree that this component renders:
View Text: Sara Text: 4 of 5 correct View Text: Quizzes: 3 Text: Streak: 7
The tree decides more than order, because a parent controls how its children are arranged. The outer View gives the card its padding and background, and it stacks its children vertically, which is the default in React Native. The inner View sets flexDirection: 'row', so its two statistics sit side by side. The Styling chapter explains this layout system. For now, notice that you added a View here because you needed a separate layout for those two children.
Tags must also close in the reverse order of opening, because each child has to end inside its parent. Writing <View><Text>Sara</View></Text> stops the build with Expected corresponding JSX closing tag for <Text>.
Grouping Without an Extra View: Fragments
Sometimes you need one parent only to satisfy the rule, and you have no use for a real view. A Fragment, written <> and </>, groups elements without creating anything on the screen:
function CardHeader() { return ( <> <Text>Sara</Text> <Text>4 of 5 correct</Text> </> ); }
Here is the difference it makes. We placed each version of CardHeader inside an outer View and printed the tree that resulted.
With a wrapper View:
View View Text: Sara Text: 4 of 5 correct
With a Fragment:
View Text: Sara Text: 4 of 5 correct
The two Text elements in the Fragment version are direct children of the outer View, so the outer View arranges them. A wrapper View adds a level to the tree and a layout box of its own, even though React Native can sometimes remove a view that affects only layout. A Fragment never creates a view.
Choose based on what you need from the parent. A Fragment cannot take a style, so use a View when the group needs padding, a background, or its own arrangement of children. Use a Fragment when the group exists only because a function must return one value. The short form also cannot take any attributes. The long form, <Fragment> imported from react, accepts a key for use in lists.
Nesting Text Inside Text
Text can also be a parent, but it behaves differently from View. Everything inside a Text uses text layout, so its children flow inline and wrap at the end of a line, as words do:
<Text style={{ fontWeight: 'bold' }}> Score: <Text style={{ color: 'teal' }}>80 percent</Text> </Text>
This displays one line in which all the text is bold and the last two words are also teal, because a nested Text inherits the styles of its parent Text. Style inheritance exists only within Text. A fontSize or color set on a View does not pass down to the Text elements inside it, as it would in a web page. Use Text as a parent for pieces of a single sentence, and use View to group separate blocks.
Reading Progress
0%
On This Page
Wrapping Elements in a View
How Nesting Forms a Tree
Grouping Without an Extra View: Fragments
Nesting Text Inside Text