Guide: Creating React Native ⚛️ App For Our Design Studio Application – Part 2

Let’s now check what is the default code added to our App.tsx file and move on to developing it further.

Check our mobile app here: https://github.com/MIRA-Designs/DesignStudioMobileApp

What We’ve Accomplished:

📍 Current Status:

Location: ~/react/DesignStudioMobileApp
Git Branch: main
Project: React Native app with default template

  1. Created React Native app with default template
  2. Renamed app from “DesignStudioApp” to “DesignStudioMobileApp”
  3. Fixed registration errors in iOS AppDelegate
  4. Renamed project folder to match app name
  5. Clean git history with 2 meaningful commits
  6. App running successfully on iOS simulator

Ready for Next Steps:

Our DesignStudioMobileApp is ready for development!

Pending work options:

  • 🧭 Add navigation between screens (React Navigation)
  • 🎨 Create custom UI components for design studio features
  • 📸 Add camera/image functionality for capturing designs
  • 💾 Set up state management (Redux/Zustand)
  • 🎯 Build specific features like project gallery, design tools, etc.
  • 📱 Customize the welcome screen and app styling

🔥 Why My MacBook Heats Up when do react native development:

Our laptop heating up when running npx react-native run-ios is actually very common in React Native development. Here’s why this happens and how to reduce it:

1. Multiple Heavy Processes Running Simultaneously:

  • Metro Bundler – JavaScript bundling and hot reloading
  • Xcode Build System – Compiling iOS native code
  • iOS Simulator – Running a virtual iPhone with full OS
  • Node.js processes – Package management and tooling
  • CocoaPods – iOS dependency management

2. Resource-Intensive Operations:

  • JavaScript compilation and transformation
  • iOS native code compilation (Objective-C/Swift)
  • File watching for hot reload (monitoring thousands of files)
  • Real-time bundling of JavaScript modules

🛠️ Solutions to Reduce Heat & CPU Usage:

Option 1: Optimize Metro Bundler 🎯

Quick Heat Reduction Tips: 💡

1. Use Release Build for Testing (Cooler):

# Instead of debug build (hot)
npx react-native run-ios --configuration Release

2. Reduce Metro File Watching:

# Start Metro with fewer watchers
npx react-native start --max-workers=2

3. Close Unnecessary Apps:

  • Close other heavy applications (browsers with many tabs, etc.)
  • Quit unused developer tools

Option 2: Optimize Metro Configuration ⚙️

Let’s update your Metro config to be more efficient:

Option 3: Alternative Development Strategies 🎯

A. Use Physical Device Instead of Simulator:

# Connect iPhone via USB, then:
npx react-native run-ios --device

Physical device uses less CPU than simulator

B. Split Development Process:

# Terminal 1: Start Metro (keep running)
npx react-native start

# Terminal 2: Build only when needed
npx react-native run-ios --no-packager

C. Use Flipper Alternative (Lighter):

# Disable Flipper in development
npx react-native run-ios --no-flipper

Option 4: System-Level Optimizations 🖥️

1. Monitor CPU Usage:

# Check what's using CPU
top -o cpu

# Or use Activity Monitor app

2. Reduce Background Processes:

  • Close unnecessary browser tabs
  • Quit Slack, Discord, etc. during development
  • Close other IDEs/editors

3. Improve Cooling:

  • Use laptop cooling pad
  • Work in cooler environment
  • Ensure laptop vents aren’t blocked

Option 5: Alternative Tools 🛠️

A. Expo Development Build (Lighter):

# If you want to switch to Expo (much lighter)
npx create-expo-app --template

B. React Native Web for Quick Testing:

# Test on web browser (much lighter)
npm install react-native-web
npx react-native run-web

📊 Expected CPU Reduction:

MethodCPU ReductionTrade-off
Release Build40-60%Slower debugging
Reduced Workers20-30%Slower builds
Physical Device30-50%Need iPhone/cable
Disable Flipper15-25%Less debugging tools
Web Testing70-80%Not native experience

🎯 Recommended Approach:

For your DesignStudioMobileApp:

  1. Use the optimized Metro config I just created ✅
  2. Start with release builds for general testing
  3. Switch to debug only when you need debugging
  4. Use physical device if you have an iPhone

Test the optimized setup:

npx react-native start --reset-cache --max-workers=2

Started Metro with the optimized settings.

🌡️ This Should Reduce Heat Significantly:

What we just optimized:

  • Reduced workers from default (~8) to 2
  • Limited file watching
  • Optimized bundling process
  • Reduced concurrent operations

Try running your app now:

npx react-native run-ios --configuration Release

This combination should reduce CPU usage by 30-50% and make your laptop run much cooler! 🎉

Quick tip: The heating is normal for React Native development, but these optimizations should make it much more manageable. Monitor Activity Monitor to see the CPU reduction! 📊


Explain the App.tsx file content

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 */

import { NewAppScreen } from '@react-native/new-app-screen';
import { StatusBar, StyleSheet, useColorScheme, View } from 'react-native';

function App() {
  const isDarkMode = useColorScheme() === 'dark';

  return (
    <View style={styles.container}>
      <StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} />
      <NewAppScreen templateFileName="App.tsx" />
    </View>
  );
}

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

export default App;

Lines 1-6: Comments and Documentation 📚

/**
 * Sample React Native App
 * https://github.com/facebook/react-native
 *
 * @format
 */
  • Lines 1-5: JSDoc comment block describing the file
  • Line 4: @format tells Prettier to auto-format this file
  • Purpose: Documentation and tooling instructions

Lines 8-9: Import Statements 📦

import { NewAppScreen } from '@react-native/new-app-screen';
import { StatusBar, StyleSheet, useColorScheme, View } from 'react-native';

Line 8:

  • import { NewAppScreen } – Imports the default welcome screen component
  • from '@react-native/new-app-screen' – From React Native’s built-in new app package
  • Purpose: Gets the pre-built welcome screen with React Native logo and links

Line 9:

  • StatusBar – Controls the phone’s status bar (battery, time, signal)
  • StyleSheet – Creates optimized styles (like CSS)
  • useColorScheme – Hook to detect if device is in dark/light mode
  • View – Basic container component (like <div> in HTML)
  • from 'react-native' – All from the core React Native library

Lines 11-19: Main App Component ⚛️

function App() {
  const isDarkMode = useColorScheme() === 'dark';

  return (
    <View style={styles.container}>
      <StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} />
      <NewAppScreen templateFileName="App.tsx" />
    </View>
  );
}

Line 11:

function App() {
  • Declares the main App component as a function
  • This is the root component of your entire app
  • Alternative: Could also write as const App = () => {

Line 12:

const isDarkMode = useColorScheme() === 'dark';
  • useColorScheme() – React Hook that returns ‘dark’, ‘light’, or null

Line 15:

<View style={styles.container}>
  • <View> – Container component (like <div> in web)
  • style={styles.container} – Applies CSS-like styles defined below
  • Purpose: Wraps all app content in a styled container

Line 16:

<StatusBar barStyle={isDarkMode ? 'light-content' : 'dark-content'} />
  • <StatusBar> – Controls the phone’s top status bar appearance
  • barStyle – Sets color of status bar text/icons
  • isDarkMode ? – Ternary operator (if/else in one line)
  • 'light-content' – White text (for dark backgrounds)
  • 'dark-content' – Dark text (for light backgrounds)
  • Purpose: Makes status bar readable in both dark/light modes

Line 17:

<NewAppScreen templateFileName="App.tsx" />
  • <NewAppScreen> – React Native’s default welcome screen component
  • templateFileName="App.tsx" – Tells the component which file it’s in
  • Purpose: Shows the welcome screen with React Native logo, docs links, etc.

Lines 21-26: Styling 🎨

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

Line 21:

const styles = StyleSheet.create({
  • StyleSheet.create() – Creates optimized style objects
  • Benefits: Performance optimization, validation, auto-completion
  • Alternative: Could use plain objects, but StyleSheet is better

Lines 22-24:

container: {
  flex: 1,
},
  • container – Style name (can be anything you want)
  • flex: 1 – Takes up all available space
  • CSS equivalent: flex: 1 makes the View expand to fill the screen
  • Purpose: Ensures the app content fills the entire screen

Line 28: Export Statement 📤

export default App;
  • export default – Makes the App component available to other files
  • Purpose: Allows index.js to import and register this component
  • Required: Without this, React Native can’t find your app component

🔄 How It All Works Together:

Flow of Execution:

  1. Import dependencies → Get required React Native components
  2. Define App component → Create the main component function
  3. Detect color scheme → Check if user prefers dark/light mode
  4. Render UI → Return JSX that describes the screen
  5. Apply styles → Style the container to fill screen
  6. Export component → Make it available to React Native

Visual Structure:

📱 Phone Screen
├── 📊 StatusBar (adapts to dark/light mode)
└── 📦 View (container that fills screen)
    └── 🎉 NewAppScreen (welcome screen with React Native content)

Key Concepts:

ConceptExplanationExample
JSXHTML-like syntax in JavaScript<View> instead of <div>
ComponentsReusable UI pieces<StatusBar>, <View>
PropsData passed to componentsbarStyle="dark-content"
HooksFunctions that add React featuresuseColorScheme()
StylesCSS-like styling for React NativeStyleSheet.create()

React Native vs Web Differences:

Web (HTML/CSS)React NativePurpose
<div><View>Container
CSS filesStyleSheetStyling
Media queriesuseColorScheme()Responsive design
Manual status bar<StatusBar>System UI control

🎯 What You’re Seeing on Screen:

When you run this app, you see:

  • React Native logo
  • “Welcome to React Native” text
  • Links to documentation
  • Step-by-step instructions
  • Status bar that adapts to your phone’s theme

This is the default template – a starting point for building our DesignStudioMobileApp! 🚀


⚛️ Functional vs Class Components in React

TypeIntroduced InSimpler SyntaxSupports HooksUses this?
Functional ComponentReact since beginning, became more powerful in React 16.8✅ Yes✅ Yes❌ No
Class ComponentReact 0.13+❌ Verbose❌ Old pattern✅ Yes

🧩 1. Functional Component (Modern)

✅ What is it?

A JavaScript function that returns JSX.
As of React 16.8, functional components can manage state and side effects using Hooks (useState, useEffect, etc.).

📦 Example:

import React, { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0); // hook

  return (
    <div>
      <h2>Count: {count}</h2>
      <button onClick={() => setCount(count + 1)}>Increment</button>
    </div>
  );
}

✅ Clean, short, and modern — preferred in most cases today.

🧱 2. Class Component (Old-style)

✅ What is it?

A JavaScript class that extends React.Component, and uses this.state, this.props, and lifecycle methods like componentDidMount.

📦 Example:

import React, { Component } from 'react';

class Counter extends Component {
  constructor(props) {
    super(props);
    this.state = { count: 0 };
  }

  increment = () => this.setState({ count: this.state.count + 1 });

  render() {
    return (
      <div>
        <h2>Count: {this.state.count}</h2>
        <button onClick={this.increment}>Increment</button>
      </div>
    );
  }
}

⚠️ More boilerplate, needs this, not as concise.

🤔 Why Two Types?

🧪 Historical Reason:

  • Before React 16.8, only class components could have state or lifecycle methods.
  • Functional components were stateless-only.

💡 Then came Hooks (React 16.8):

  • Gave functional components full power: state, side effects, refs, context.
  • Made class components mostly obsolete for new code.

🧠 Which One Should You Use?

Use Functional Components unless:

  • You’re working with legacy code
  • You’re learning how React evolved
  • A library forces you into class-style APIs (rare now)

✅ TL;DR

FeatureFunctional ComponentClass Component
SyntaxSimple functionClass with extends Component
State support✅ Yes (via Hooks)✅ Yes
Lifecycle methods✅ Yes (via Hooks like useEffect)✅ Yes (componentDidMount, etc)
this keyword❌ No✅ Yes
Modern React choice⭐ PreferredDeprecated for new apps

Absolutely! Let’s go over the most important React Hooks that turned functional components into full-featured building blocks, just like class components (and even more powerful!).


⚛️ React Hooks — Power Tools for Functional Components

Introduced in React 16.8, Hooks let you:

  • Use state, side effects, context, refs, etc.
  • Without writing a class component

🧰 Essential React Hooks (with Examples)

1️⃣ useState — Manage Local Component State 🧠

📌 When to Use:

To store and update component-level state (like a counter, input field value, toggle, etc.)

✅ Example:

import { useState } from 'react';

function Counter() {
  const [count, setCount] = useState(0); // initial value = 0

  return (
    <div>
      <h3>Count: {count}</h3>
      <button onClick={() => setCount(count + 1)}>+1</button>
    </div>
  );
}

2️⃣ useEffect — Handle Side Effects ⏳

📌 When to Use:

To run code after render: API calls, timers, subscriptions, etc.
(Just like componentDidMount, componentDidUpdate, componentWillUnmount)

✅ Example:

import { useEffect, useState } from 'react';

function UserProfile({ userId }) {
  const [user, setUser] = useState(null);

  useEffect(() => {
    fetch(`/api/users/${userId}`)
      .then(res => res.json())
      .then(data => setUser(data));
  }, [userId]); // runs again if userId changes

  return <div>{user ? user.name : 'Loading...'}</div>;
}

The useEffect hook in React takes two parameters:

🧠 useEffect Syntax

useEffect(effectFunction, dependencyArray)
ParameterTypeRequiredPurpose
effectFunction() => {}✅ YesCode to run after render (can include async logic)
dependencyArray[] (array)✅ YesList of values to watch — effect re-runs only if these change

🔁 Our Example Breakdown

useEffect(() => {
  fetch(`/api/users/${userId}`)
    .then(res => res.json())
    .then(data => setUser(data));
}, [userId]);

1. First Argument: Arrow Function () => { ... }

  • This function runs after the component renders.
  • It performs a side effect (API call).
  • You can also return a function for cleanup (like removing event listeners).

2. Second Argument: Dependency Array [userId]

  • This tells React:
    “Only re-run this effect if userId changes.
  • If userId stays the same between renders → the effect won’t run again.
  • If omitted → the effect runs on every render.
useEffect(() => {
  console.log("Runs after every render!");
});

⚠️ This runs after every single re-render, which can be expensive.


3️⃣ useContext — Access Context (Global Data) 🌐

📌 When to Use:

To consume global values like theme, language, authentication, etc., without prop drilling.

✅ Example:

import { useContext } from 'react';
import { ThemeContext } from './ThemeProvider';

function ThemedButton() {
  const theme = useContext(ThemeContext); // 'dark' or 'light'

  return <button style={{ background: theme === 'dark' ? '#333' : '#eee' }}>Click</button>;
}

4️⃣ useRef — Store a Mutable Reference 🪞

📌 When to Use:

To reference DOM elements or store values without causing re-renders.

✅ Example:

import { useRef } from 'react';

function InputFocus() {
  const inputRef = useRef();

  return (
    <div>
      <input ref={inputRef} />
      <button onClick={() => inputRef.current.focus()}>Focus</button>
    </div>
  );
}

5️⃣ useMemo — Memoize Expensive Computations 🧮

📌 When to Use:

To cache the result of heavy functions, only recomputing when dependencies change.

✅ Example:

import { useMemo } from 'react';

function ExpensiveList({ items }) {
  const sortedItems = useMemo(() => {
    return [...items].sort(); // costly operation
  }, [items]);

  return <ul>{sortedItems.map(i => <li key={i}>{i}</li>)}</ul>;
}

6️⃣ useCallback — Memoize Functions to Avoid Re-Creation 🎯

📌 When to Use:

To prevent unnecessary re-renders when passing callbacks to child components.

✅ Example:

import { useState, useCallback } from 'react';

function Parent() {
  const [count, setCount] = useState(0);

  const increment = useCallback(() => setCount(c => c + 1), []);

  return <Child onClick={increment} />;
}

(Bonus) useReducer — Complex State Logic ⚙️

📌 When to Use:

To manage complex state transitions or when you’d use redux-like reducers.

✅ Example:

import { useReducer } from 'react';

function reducer(state, action) {
  switch (action.type) {
    case 'inc': return { count: state.count + 1 };
    case 'dec': return { count: state.count - 1 };
    default: return state;
  }
}

function Counter() {
  const [state, dispatch] = useReducer(reducer, { count: 0 });

  return (
    <>
      <p>Count: {state.count}</p>
      <button onClick={() => dispatch({ type: 'inc' })}>+1</button>
    </>
  );
}

✅ TL;DR – Hook Summary Table

HookPurposeReplaces
useStateState inside function componentthis.state / setState
useEffectSide effects (API, timers, etc.)componentDidMount etc.
useContextUse global context valuescontextType, props drilling
useRefDOM ref or persistent valuescreateRef
useMemoCache a computed valueManual memoization
useCallbackCache a functionInline anonymous functions
useReducerComplex state logic (like Redux)Multiple useState calls

Handy booklet:


Let’s see in Part 3.. Happy React Native Development 🚀