Grokking React Native
Vote

0% completed

​

Nesting Elements in JSX

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 nested tags of ProfileCard form a tree, and the position of each element on the screen follows from its parent.
The nested tags of ProfileCard form a tree, and the position of each element on the screen follows from its parent.

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
A wrapper View adds one more level to the tree, while a Fragment leaves its children directly under the outer parent.
A wrapper View adds one more level to the tree, while a Fragment leaves its children directly under the outer parent.

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%


Vote for new content

On This Page

Wrapping Elements in a View

How Nesting Forms a Tree

Grouping Without an Extra View: Fragments

Nesting Text Inside Text