Build Real-World React Native App setups, issues faced, and tips
Tags: reactnative, android, typescript, mobile
Published: 2021-04-28 04:18:53

This blog post is about will give you complete knowledge about how to start with react-native using typescript.

Keep in mind that if you get stuck on any step, refer to the [https://reactnative.dev/docs/getting-started](Link)

### Creating the Project
Using the React Native CLI we can generate the project with TypeScript pre-installed.


> react-native init myapp --template typescript && node myapp/setup.js && cd myapp

NPX is a package runner for NPM, and it’s available since NPM 5.2. With NPX there’s no need to install the ‘react-native-cli’ package globally just to initialize our project.

The ‘ — template react-native-template-typescript’ parameter will use the Typescript template to create the project. I always use Typescript for static type checking, it will make things more developer-friendly and less prone to errors.

The ‘ — npm’ parameter will make the project use NPM instead of Yarn to install initial dependencies.

### Setting Up TSLint
Next, we want to set up linting. I like a combination of three rules:
```javascript
tslint-eslint-rules
tslint-react
tslint-config-prettier
```
You can check out what the respective configuration does by clicking on it. Let’s install these rules together with TSLint now.

> npm install --save-dev tslint tslint-eslint-rules tslint-react tslint-config-prettier

Consequently, we want to set up a tslint.json file. In it, you can fine-tune your linting configuration (below you'll see my personal preference).

You might also want to change the lib key in your tsconfig.json from ["es6"] to ["es2017"] to have access to newer syntax such as Object.value.

If your editor supports TSLint integration, it should already complain about the empty Props interface in App.tsx¹. If your editor does not, add the following value to your scripts key in your package.json:

> "lint": "tslint --project tsconfig.json"

Now you can lint using your terminal.

> npm run lint

If you set up everything correctly, this will yell at you about the empty interface in App.js.

### Initial directory and file changes
I like to move all of the project javascript source files to an ‘src’ directory to keep the project root nice and tidy. Then I move the **‘App.tsx’** file from the project root to the ‘src’ directory. Finally, because we’re using Typescript in the project, I rename the ‘index.js’ file to ‘index.ts’.

### React Event Handlers with TypeScript
The React event system is a wrapper around the browser’s native event system. TypeScript types for this event system are available in the **@types/react** npm package. These types can be used to strongly-type event parameters. Some of the common ones are:

* ChangeEvent<T>
* KeyboardEvent<T>
* MouseEvent<T>
* FormEvent<T>

These types are all derived from **SyntheticEvent<T>**.

####Sample Examples
```javascript
update = (e: React.SyntheticEvent): void => {
    let target = e.target as HTMLInputElement;
    this.props.login[target.name] = target.value;
}

// Also for events instead of React.SyntheticEvent, you can also type
// them as following: Event, MouseEvent, KeyboardEvent...etc,
// depends on the use case of the handler.
update = (e: React.FormEvent<EventTarget>): void => {
    let target = e.target as HTMLInputElement;
    this.props.login[target.name] = target.value;
}

function update(e: React.ChangeEvent<HTMLInputElement>) {
    this.props.login[target.name] = e.target.value;
  }
```
I have the following in a types.ts file for html input, select, and textarea globally:

```javascript
export type InputChangeEventHandler = React.ChangeEventHandler<HTMLInputElement>
export type TextareaChangeEventHandler = React.ChangeEventHandler<HTMLTextAreaElement>
export type SelectChangeEventHandler = React.ChangeEventHandler<HTMLSelectElement>
```
Then import them:
```javascript
import { InputChangeEventHandler } from '../types'
```

Then use them:
```javascript
const updateName: InputChangeEventHandler = (event) => {
  // Do something with `event.currentTarget.value`
}
const updateBio: TextareaChangeEventHandler = (event) => {
  // Do something with `event.currentTarget.value`
}
const updateSize: SelectChangeEventHandler = (event) => {
  // Do something with `event.currentTarget.value`
}
```
hen apply the functions on your markup (replacing ... with other necessary props):
```javascript
<input onChange={updateName} ... />
<textarea onChange={updateName} ... />
<select onChange={updateSize} ... >
  // ...
</select>
```
for update: event: React.ChangeEvent for submit: event: React.FormEvent for click: event: React.MouseEvent.

### Events Calls
* onClick - An onClick event occurs when a user clicks on an element. 
* onChange - onChange events happen when the value inside of an element is changed.
* onBlur - onBlur event happens when an element loses focus.

### React-native clean gradle cache
```javascript
#Win
cd android && gradlew clean && cd .. && react-native run-android

#osX
cd android && bash gradlew clean && cd .. && react-native run-android --variant=release

```
### Execution failed for task ':react-native-gesture-handler:compileDebugJavaWithJavac:

####Method 1
```javascript 
Click in react-native-gesture-handler project on android studio
Click in Refactor on top
Click Migrate to AndroidX.
```
####Method 2
```javascript
// 1.- Add jetifier as dev dependency
yarn install jetifier --dev

// 2.- Add a task in package.json inside of "scripts" tag,

"scripts": {
....
"jetify": "npx jetify"
}
// 3.- Run as yarn
yarn jetify
```

###Un Used packages identification

With the wide availability of packages in NPM, we very often tend to add plenty of packages. With time, and due to poor management of code, the dependency tree grows and adds extra weight to the bundle.

Identifying and removing unused dependencies manually would be a hideous process. Thankfully, we have yet another package available in NPM to identify the unused dependencies in our package.json file.

#### Depcheck:
Depcheck analyses package.json to output: how each dependency is used, all the redundant dependencies, and the missing dependencies.
The process is pretty simple. All you have to do is the usual:

> npm install -g depcheck

####How to use it 
> depcheck [directory] [arguments]

The directory argument is the root directory of your project (where the package.json file is). If unspecified defaults to the current directory.

####Example
The following example checks the dependencies under /path/to/my/project folder:
```javascript
$> depcheck /path/to/my/project
Unused dependencies
* underscore
Unused devDependencies
* jasmine
Missing dependencies
* lodash
```
#### Gradle does not find tools.jar

> echo export "JAVA_HOME=\$(/usr/libexec/java_home)" >> ~/.bash_profile

Restart shell ....

#### Execution failed app:processDebugResources Android Studio

Cleaned the project Steps : **Menubar -> Build -> Clean Project ** and then did the build again. It worked.



Thanks for reading it through, I welcome any feedback regarding this topic. 

Next week will post about what I developed on react native step by step.