JavaScript to TypeScript in React-Native Development
Tags: typescript, reactnative, mobile
Published: 2024-07-16 16:55:14

## TypeScript in React Native: My Journey from Confusion to Clarity

After a year of working with JavaScript, I was encouraged to learn TypeScript as I embarked on my mobile development journey. Having a solid foundation in React made the transition to React Native smoother. However, TypeScript introduces a new level of syntax complexity. In this guide, I will outline some key differences to assist new learners in their approach. I'll also share a crucial adjustment when moving from React to React Native in terms of styling. We'll explore these concepts through a fun project: a React Native app that fetches and displays city and state information based on a zip code.

## Embracing TypeScript

Transitioning from JavaScript to TypeScript is like leveling up. Initially, I felt a lot of internal pushback, questioning the necessity since JavaScript works fine and I felt comfortable with it. However, after jumping into learning TypeScript on Codecademy, I gained skills that make my code more reliable and maintainable.

JavaScript is flexible and forgiving, which can lead to hard-to-catch bugs. TypeScript adds static types to JavaScript, helping you catch errors at compile time. This can save hours of debugging and make your code more robust. As JavaScript was the first language I learned, I didn't initially understand the benefits of rigidity. However, after diving into more languages, I now appreciate its perks.

JavaScript and TypeScript are similar, but differ in a few fundamental ways:

1. **Static Typing**: TypeScript allows you to define types for your variables, function parameters, and return values.
2. **Interfaces**: You can define custom types using interfaces.

```typescript
interface User {
  name: string;
  age: number;
}
let user: User = { name: "Rafi", age: 22 };
```
3. **Generics**: TypeScript supports generics, allowing you to create reusable and type-safe components.

```typescript
function identity<T>(arg: T): T {
  return arg;
}
let output = identity<string>("Hello");
```
4. **Type Inference**: TypeScript can infer types based on the values you assign, reducing the need for explicit type annotations.

I am reminded of my time switching from DOM manipulation to React, where I took my old DOM manipulation projects and slowly reworked them. This process helped me internalize the exact differences in approach and workflow. I think the best way to learn and internalize is with an example, so let's dive into a React Native project and see how we can mentally switch from JavaScript to TypeScript. Fetching from external APIs is always a muscle I'm trying to flex, so I'll use that as an example:

##City and State Info Fetcher

**Objective**:Create a React Native app that fetches and displays city and state information based on a zip code.

##Implementation

1. **Setup**: Initialize a new React Native project and install necessary dependencies.
```bash
npx react-native init CityInfoApp
cd CityInfoApp
npm install axios
```
2. **Create Components**: Create a component for input and displaying results.
3. **Fetch Data**: Use Axios to fetch data from an API.
4. **TypeScript Integration**: Add types for better code quality.

First, I made a "sketch" in javascript. I am coding both to highlight the differences in syntax.

```javascript
import React, { useState } from 'react';
import { ImageBackground, StyleSheet, Text, TextInput, TouchableOpacity, View } from 'react-native';
import { getUsersLocation } from './src/fetch-utils';

export default function App() {
  const [zipCode, setZipCode] = useState('');
  const [location, setLocation] = useState(null);
  const [error, setError] = useState(null);

  const handleSubmit = async () => {
    let urlToGrab = `http://ZiptasticAPI.com/${zipCode}`;

    try {
      const locationData = await getUsersLocation(urlToGrab);
      setLocation(locationData);
      setError(null);
    } catch (error) {
      setLocation(null);
      setError('Error getting location data');
    }
  };
```

### Converting to TypeScript

The conversion process is straightforward. We'll start by renaming file extensions from `.js` to `.tsx`. Then, we'll add type annotations.

#### Adding Type Annotations

We'll define the types for our state and props. 

```typescript
import React, { useState } from 'react';
import { ImageBackground, StyleSheet, Text, TextInput, TouchableOpacity, View } from 'react-native';
import { getUsersLocation } from './src/fetch-utils';

interface Location {
  city: string;
  state: string;
}

export default function App() {
  const [zipCode, setZipCode] = useState<string>('');
  const [location, setLocation] = useState<Location | null>(null);
  const [error, setError] = useState<string | null>(null);

  const handleSubmit = async () => {
    let urlToGrab = `http://ZiptasticAPI.com/${zipCode}`;

    try {
      const locationData = await getUsersLocation(urlToGrab);
      setLocation(locationData);
      setError(null);
    } catch (error) {
      setLocation(null);
      setError('Error getting location data');
    }
  };
```

Now let's add some styling!

## Styling in React Native

Styling in React Native is similar to using CSS in web development but with some key differences. React Native uses a JavaScript object to define styles, which are then applied to components. There isn't a CSS file. 

### Key Differences

1. **StyleSheet**: Styles are created using the `StyleSheet.create` method.
2. **Flexbox**: Layouts are managed using Flexbox, similar to CSS Flexbox but with some differences in default behavior.
3. **No Cascade**: Styles do not cascade as they do in CSS. Each component has its own styles.

#### Example Styles

Here's how I styled the app using React Native's `StyleSheet`:

```typescript
const styles = StyleSheet.create({
  background: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
  },
  container: {
    flex: 1,
    alignItems: 'center',
    justifyContent: 'center',
    padding: 16,
    width: '100%',
    borderRadius: 30,
    marginTop: '-40%',
  },
  header: {
    fontSize: 24,
    color: 'white',
    marginBottom: 20,
    fontWeight: 'bold',
  },
  inputContainer: {
    backgroundColor: 'rgba(255, 255, 255, 0.6)',
    borderRadius: 10,
    padding: 20,
    alignItems: 'center',
    width: '80%',
  },
  input: {
    width: '100%',
    padding: 10,
    borderColor: 'white',
    borderWidth: 1,
    borderRadius: 25,
    marginBottom: 20,
    color: 'navy',
    backgroundColor: 'white',
  },
  button: {
    backgroundColor: '#98e9ff',
    padding: 10,
    borderRadius: 10,
  },
  buttonText: {
    color: 'white',
    fontWeight: 'bold',
  },
  result: {
    marginTop: 20,
    fontSize: 18,
    color: 'navy',
    fontWeight: 'bold',
  },
  error: {
    marginTop: 20,
    fontSize: 18,
    color: 'red',
  },
});
```


## Conclusion

Switching from JavaScript to TypeScript and styling in React Native can initially seem daunting, but the benefits are well worth the effort. TypeScript's type safety and improved code readability, combined with React Native's powerful styling capabilities, make for a robust and maintainable codebase. Happy coding!