DEV Community

Cover image for Build Real-World React Native App setups, issues faced, and tips
Selva kumar
Selva kumar

Posted on • Updated on

Build Real-World React Native App setups, issues faced, and tips

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

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:

tslint-eslint-rules
tslint-react
tslint-config-prettier
Enter fullscreen mode Exit fullscreen mode

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
  • KeyboardEvent
  • MouseEvent
  • FormEvent

These types are all derived from SyntheticEvent.

Sample Examples

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;
  }
Enter fullscreen mode Exit fullscreen mode

I have the following in a types.ts file for html input, select, and textarea globally:

export type InputChangeEventHandler = React.ChangeEventHandler<HTMLInputElement>
export type TextareaChangeEventHandler = React.ChangeEventHandler<HTMLTextAreaElement>
export type SelectChangeEventHandler = React.ChangeEventHandler<HTMLSelectElement>
Enter fullscreen mode Exit fullscreen mode

Then import them:

import { InputChangeEventHandler } from '../types'
Enter fullscreen mode Exit fullscreen mode

Then use them:

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`
}
Enter fullscreen mode Exit fullscreen mode

hen apply the functions on your markup (replacing ... with other necessary props):

<input onChange={updateName} ... />
<textarea onChange={updateName} ... />
<select onChange={updateSize} ... >
  // ...
</select>
Enter fullscreen mode Exit fullscreen mode

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

#Win
cd android && gradlew clean && cd .. && react-native run-android

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

Enter fullscreen mode Exit fullscreen mode

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

Method 1

Click in react-native-gesture-handler project on android studio
Click in Refactor on top
Click Migrate to AndroidX.
Enter fullscreen mode Exit fullscreen mode

Method 2

// 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
Enter fullscreen mode Exit fullscreen mode

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:

$> depcheck /path/to/my/project
Unused dependencies
* underscore
Unused devDependencies
* jasmine
Missing dependencies
* lodash
Enter fullscreen mode Exit fullscreen mode

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.

Top comments (0)