Skip to main content
Back to module
Mobile Development Basics · React Native Tour

JSX without HTML

Reading28mLesson 3 of 3 in this module

Build screens with View, Text, Pressable and StyleSheet instead of HTML and CSS.

Why it matters

You already know React for the web, where JSX becomes HTML: <div>, <p>, <button>. React Native uses exactly the same JSX syntax, components, props and hooks, but there is no HTML and no CSS on a phone. Your JSX must use React Native's components, and styles are JavaScript objects. Knowing the mapping saves you an afternoon of "why is nothing rendering?".

The core components

Web habitReact NativeNotes
<div>, <section><View>A box for layout. It cannot hold raw text.
<p>, <span>, <h1><Text>All text must be inside <Text>.
<img><Image>Needs a source and usually a width and height.
<button>, clickable <div><Pressable> (or <Button>)onPress, not onClick.
<input><TextInput>onChangeText gives you the string directly.
page scrolling<ScrollView> or <FlatList>Views do not scroll by themselves.

The most common error for web developers is putting text straight into a View:

// Crashes with "Text strings must be rendered within a <Text> component"
<View>Hello</View>

// Correct
<View>
  <Text>Hello</Text>
</View>

Styling with StyleSheet

Styles are plain objects with camelCase property names, and numbers are density-independent pixels (no px):

import { StyleSheet, View, Text, Pressable } from "react-native";

export default function Card({ title, done, onToggle }) {
  return (
    <View style={styles.card}>
      <Text style={[styles.title, done && styles.done]}>{title}</Text>
      <Pressable onPress={onToggle} style={styles.button}>
        <Text style={styles.buttonText}>{done ? "Undo" : "Done"}</Text>
      </Pressable>
    </View>
  );
}

const styles = StyleSheet.create({
  card: { padding: 16, borderRadius: 12, backgroundColor: "#fff", flexDirection: "row", alignItems: "center" },
  title: { flex: 1, fontSize: 18 },
  done: { textDecorationLine: "line-through", color: "#666" },
  button: { paddingVertical: 8, paddingHorizontal: 12, borderRadius: 8, backgroundColor: "#2563eb" },
  buttonText: { color: "#fff", fontWeight: "600" },
});

Three things to notice:

  1. Style arrays. style={[styles.title, done && styles.done]} combines styles. Later entries win, and falsy entries (false, null, undefined) are ignored. That is how you apply conditional styles without string class names.
  2. Flexbox by default. Every View is a flex container, and the default flexDirection is column (on the web it is row). flex: 1 makes a child fill the remaining space.
  3. No cascade. Styles do not inherit from parents, except that nested <Text> inherits text styles from an outer <Text>. You cannot set a font on a View and expect the text inside to use it.

StyleSheet.create mostly helps by keeping styles in one place and validating property names in development. React Native also exports StyleSheet.flatten, which merges a style array into one object; it is handy for tests and for reading the final value of a style.

Worked example: merging styles by hand

To understand how style arrays work, imagine writing the merge yourself. Given [base, isActive && active, { opacity: 0.5 }], you walk the array left to right, skip falsy entries, flatten nested arrays and copy each object's properties over the result:

function merge(style) {
  if (!style) return {};
  if (Array.isArray(style)) {
    return style.reduce((acc, s) => Object.assign(acc, merge(s)), {});
  }
  return { ...style };
}

That small function is the whole idea behind StyleSheet.flatten. You will write your own version in the Do tab.

Common mistakes

  • Raw text in a View, or a string with a stray space between components. Wrap it in <Text>.
  • Units in strings: padding: "16px" is invalid. Use numbers (16) or percentages as strings ("50%").
  • Expecting onClick. Use onPress on Pressable.
  • Expecting the page to scroll. Wrap long content in ScrollView, and use FlatList for long lists.
  • Expecting CSS inheritance. Set text styles on the Text itself (or a parent Text).

Quick recap

  • Use View for boxes, Text for every piece of text, Pressable for touches, TextInput for typing and Image for pictures.
  • Styles are objects; combine them with arrays where later entries win and falsy ones are ignored.
  • Layout is Flexbox with column as the default direction.

Try it

In the Do tab you will write two helpers: one that maps an HTML tag to the React Native component you would use, and one that flattens a style array exactly like StyleSheet.flatten. The exercise is plain JavaScript (no JSX), so it runs in your browser.

Also in this lesson: