Blogs/Technology

Getting started with React Native for Mac

Written byMurtuza Kutub
Aug 10, 2026
7 Min Read
Getting started with React Native for Mac Hero
Too Long? Read This First

- A React Native component is a reusable function that returns JSX.
- Component names must begin with an uppercase letter.
- Use export default when a file has one primary component.
- Use named exports when a file provides multiple components or utilities.
- Default imports do not require braces; named imports do.
- The import path must point to the component’s actual file location.
- AppRegistry normally belongs in the generated index.js, not in every component.

Components are the foundation of every React Native application. Instead of building an entire screen in one file, you can divide the interface into smaller components and reuse them across screens.

In practice, we have found that separating components early makes an application easier to read, test, and maintain. However, creating too many tiny components can make navigation through the codebase unnecessarily difficult. The goal is meaningful separation, not simply creating more files.

What Is a Component in React Native?

A React Native component is a reusable piece of user interface and its related behaviour. Components can represent small elements, such as a title or button, or complete screens containing several nested components.

The React Native documentation describes components as blueprints. A function component returns a React element that tells React Native what should appear on the screen.

For example:

import {Text} from 'react-native';

function Greeting() {
  return <Text>Hello from React Native!</Text>;
}

export default Greeting;

Here, Greeting is a custom component, while Text is a core component supplied by React Native.

React Native Components vs Java Classes

React Native and Java use different programming models, so their concepts should not be treated as direct equivalents.

React NativeJava/Android
A function can define a componentA class commonly defines an Android object or UI controller
JSX describes the interfaceXML layouts or programmatic views describe the interface
Props pass data into componentsConstructors, setters, or method parameters pass data
State controls changing UI dataFields and observable state commonly manage changing data
Text displays textTextView displays text
View groups and lays out contentLayout classes such as LinearLayout group views
A function can define a component
Java/Android
A class commonly defines an Android object or UI controller
1 of 6

A JavaScript const is not equivalent to a Java class. It creates a block-scoped variable that cannot be reassigned. The value stored in that variable can be a function, object, number, string, or another JavaScript value.

For example, this code stores a component function in a constant:

const Greeting = () => {
  return <Text>Hello!</Text>;
};

You could also declare the same component with a function declaration:

function Greeting() {
  return <Text>Hello!</Text>;
}

Both approaches are valid.

How to Create a Component in React Native

Assume the project contains the following structure:

AwesomeProject/
├── App.tsx
├── index.js
└── src/
    └── components/
        └── Title.tsx

Inside src/components/Title.tsx, create the component:

import {StyleSheet, Text} from 'react-native';

function Title() {
  return <Text style={styles.title}>Hello Component!</Text>;
}

const styles = StyleSheet.create({
  title: {
    fontSize: 24,
    fontWeight: '600',
  },
});

export default Title;

This component has three main parts:

  • Text is imported from React Native.
  • Title returns the JSX that should be rendered.
  • export default Title makes the component available to other files.

The filename extension is .tsx because the project uses TypeScript and the file contains JSX. In a JavaScript project, you can place the equivalent code in Title.js or Title.jsx.

Why Must Component Names Start With an Uppercase Letter?

React distinguishes custom components from built-in elements by their capitalization.

This is treated as a custom component:

function Title() {
  return <Text>Hello</Text>;
}

It is then rendered as:

<Title />

A lowercase JSX name is treated as a built-in or platform element rather than your custom component. Therefore, names such as Title, ProfileCard, and LoginButton should begin with uppercase letters.

How to Export a React Native Component

Exporting makes a component available outside the file where it was created. JavaScript and TypeScript provide two common approaches: default exports and named exports.

Default Export

A default export works well when a file contains one primary component:

import {Text} from 'react-native';

function Title() {
  return <Text>Hello Title</Text>;
}

export default Title;

You can also export the component directly:

import {Text} from 'react-native';

export default function Title() {
  return <Text>Hello Title</Text>;
}

A file can have only one default export.

Let’s Build Your React Native App Together!

We build powerful React Native apps that run smoothly on iOS and Android — fast, reliable, and ready to scale.

Named Export

A named export is useful when the same file contains multiple components or related values:

import {Text} from 'react-native';

export function Title() {
  return <Text>Main Title</Text>;
}

export function Subtitle() {
  return <Text>Supporting text</Text>;
}

A file can contain multiple named exports.

How to Import a Component from Another File

Because Title is the default export from src/components/Title.tsx, import it in App.tsx without braces:

import {StyleSheet, View} from 'react-native';
import Title from './src/components/Title';

function App() {
  return (
    <View style={styles.container}>
      <Title />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
});

export default App;

The extension does not need to be included in the import:

import Title from './src/components/Title';

React Native’s tooling resolves the appropriate .tsx, .ts, .jsx, or .js file.

When this application runs, it displays:

Hello Component!

Importing Named Components

Named exports must be imported using braces:

import {Title, Subtitle} from './src/components/Headings';

The imported names must match the exported names:

export function Title() {
  // Component implementation
}

export function Subtitle() {
  // Component implementation
}

You can rename a named import with as:

import {Title as ScreenTitle} from './src/components/Headings';

The component can then be rendered with its new local name:

<ScreenTitle />

Default Exports vs Named Exports

Default exportNamed export
One allowed per fileMultiple allowed per file
Imported without bracesImported with braces
Can be renamed during importNormally imported using its exported name
Suitable for a file’s main componentSuitable for groups of related components
One allowed per file
Named export
Multiple allowed per file
1 of 4

Both approaches work. What matters most is applying a consistent convention across the project.

We generally use a default export when a file contains one screen or component. Named exports are more useful for grouped utilities, hooks, constants, or a closely related set of smaller components.

Passing Data to an Imported Component

Reusable components become more useful when they accept data through props. Props are values passed from a parent component to a child component.

Update Title.tsx:

import {StyleSheet, Text} from 'react-native';

type TitleProps = {
  text: string;
};

function Title({text}: TitleProps) {
  return <Text style={styles.title}>{text}</Text>;
}

const styles = StyleSheet.create({
  title: {
    fontSize: 24,
    fontWeight: '600',
  },
});

export default Title;

Pass the text prop from App.tsx:

import {StyleSheet, View} from 'react-native';
import Title from './src/components/Title';

function App() {
  return (
    <View style={styles.container}>
      <Title text="Welcome to React Native" />
    </View>
  );
}

const styles = StyleSheet.create({
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
  },
});

export default App;

The component now displays the value supplied by its parent:

Welcome to React Native

The TitleProps type also prevents the component from accidentally receiving an unsupported value. Current React Native CLI projects use TypeScript by default, according to the official TypeScript guide.

What Does AppRegistry Do?

AppRegistry is the JavaScript entry point used to register the application’s root component with the native runtime.

A Community CLI project normally contains an index.js similar to this:

import {AppRegistry} from 'react-native';
import App from './App';
import {name as appName} from './app.json';

AppRegistry.registerComponent(appName, () => App);

This code:

  1. Imports the root App component.
  2. Reads the registered application name from app.json.
  3. Registers App so the native Android or iOS runtime can launch it.

You normally do not need to modify this file or call AppRegistry.registerComponent inside reusable components. The project template creates and configures the entry point for you.

Using a Barrel File for Cleaner Imports

As a component directory grows, a barrel file can provide a single import location.

Create src/components/index.ts:

export {default as Title} from './Title';
export {default as ProfileCard} from './ProfileCard';
export {default as PrimaryButton} from './PrimaryButton';

Components can now be imported from the directory:

import {
  PrimaryButton,
  ProfileCard,
  Title,
} from './src/components';

Barrel files can improve readability, but they should be used carefully. Large barrel files may introduce circular dependencies or make it harder to identify where a component is defined.

Common Component Import and Export Errors

“Element type is invalid”

This error commonly appears when a default export is imported as a named export or the reverse.

Incorrect:

import {Title} from './src/components/Title';

Correct for a default export:

import Title from './src/components/Title';

“Unable to resolve module”

This usually indicates an incorrect path, filename, capitalization, or file location.

Let’s Build Your React Native App Together!

We build powerful React Native apps that run smoothly on iOS and Android — fast, reliable, and ready to scale.

For example, if App.tsx and the src directory are at the same level, use:

import Title from './src/components/Title';

File paths can be case-sensitive in build environments even when they appear forgiving during local development.

Component name begins with lowercase

Incorrect:

function title() {
  return <Text>Hello</Text>;
}

Correct:

function Title() {
  return <Text>Hello</Text>;
}

Importing a component that was never exported

Defining a component does not automatically expose it to other files. Add either a default or named export:

export default Title;

or:

export {Title};

Declaring two components with the same name

The original example imports App and then declares another App in the same file. That produces a duplicate identifier error. Imported components and locally declared components must use distinct names.

There is no mandatory folder structure, but a small project can begin with:

src/
├── components/
│   ├── PrimaryButton.tsx
│   ├── ProfileCard.tsx
│   └── Title.tsx
├── screens/
│   ├── HomeScreen.tsx
│   └── ProfileScreen.tsx
└── hooks/
    └── useProfile.ts

Keep broadly reusable UI elements inside components. Components that represent complete application screens belong in screens, while reusable stateful logic can be placed in custom hooks.

Avoid moving every piece of JSX into a separate file. A component is worth extracting when it is reused, has its own behaviour, represents a meaningful interface section, or makes the parent component substantially easier to understand.

FAQ

What is a component in React Native?

A component is a reusable function or class that describes part of the application interface. It can accept props, manage state, render native elements, and contain other components.

What is the difference between default and named exports?

A file supports one default export but multiple named exports. Default imports omit braces, while named imports use braces and must match the names exported by the source file.

Do React Native components need to be classes?

No. Modern React Native applications primarily use function components with Hooks. Class components remain supported, but function components usually require less boilerplate and work naturally with current React patterns.

Should reusable components use .js or .tsx files?

Use .tsx when the project uses TypeScript and the file contains JSX. JavaScript projects can use .js or .jsx, depending on the project’s established naming convention.

Does every component need AppRegistry?

No. Only the application’s root component is registered through AppRegistry. Reusable components are exported from their files, imported into other components, and rendered using JSX.

Conclusion

Creating a React Native component involves defining a function that returns JSX. Exporting exposes that component to other files, while importing allows it to be rendered elsewhere in the application.

For reliable imports, match default and named export syntax, use the correct relative path, capitalize component names, and keep AppRegistry limited to the application entry point.

Author-Murtuza Kutub
Murtuza Kutub
LinkedIn

A product development and growth expert, helping founders and startups build and grow their products at lightning speed with a track record of success. Apart from work, I love to Network & Travel.

Share this article

Phone

Next for you

8 Best GraphQL Libraries for Node.js in 2025 Cover

Technology

Aug 4, 202613 min read

8 Best GraphQL Libraries for Node.js in 2025

8 Best GraphQL Libraries for Node.js in 2026 Too Long? Read This First - Choose Apollo Server when you need a mature ecosystem, GraphOS integration, plugins, or Apollo Federation. - Choose GraphQL Yoga for a modern, portable server with Fetch API compatibility and built-in support for subscriptions over Server-Sent Events. - Choose Mercurius when your application already uses Fastify and runtime efficiency is a major priority. - Use GraphQL.js when you need the official JavaScript implementati

9 React Native Animation Libraries and Tools Compared Cover

Technology

Aug 4, 202615 min read

9 React Native Animation Libraries and Tools Compared

Too Long? Read This First - Use React Native Reanimated for gesture-driven, interruptible, and performance-sensitive interface animations. - Use the built-in Animated API for simple fades, transforms, and timed sequences without another dependency. - Pair React Native Gesture Handler with Reanimated for swipes, dragging, pinching, rotation, and other touch-driven experiences. - Use Lottie React Native for non-interactive motion graphics supplied by designers. - Choose React Native Skia for cust

9 Critical Practices for Secure Web Application Development Cover

Technology

Aug 4, 202616 min read

9 Critical Practices for Secure Web Application Development

Too Long? Read This First - Define security requirements and model threats before implementation begins. - Treat authentication, account recovery, and MFA as one complete identity system. - Apply server-side authorization to every protected action and object. - Prevent injection with parameterized APIs, structured validation, safe output handling, and restricted outbound requests. - Protect sessions and tokens throughout their complete lifecycle. - Minimise sensitive data and manage encryption