React-Native — Tips, Structure & Solutions for your project

Better structure and tips for your redux + react navigation + typescript RN project!

Panagiotis Vrs
ITNEXT

--

For some time now i was gathering information from all the applications i made using the React Native framework for both the bad and the good practises i am doing. So i decided i could share some information that might help someone out there!

Use Types early in the project

Doesn’t matter how big or small your project is at first if you think that the application you make would scale in the future it is good to start early. Types would help you avoiding errors when your application would be live and that it would be hard to debug and slow to push any fix to it by publishing a new version. Also its hard to transform an existing project slowly to typescript and keep a structure of your types.

Navigation, Navigation, Navigation

This would be your heart of the system. There aren’t any app without a navigation from one screen to another (except hello world RN example app 😃). There aren’t many libraries that are getting much attention in the react native ecosystem but i think that the one RN is promoting and i think it is worth it is React Navigation and is going to be 99% what you are looking for. I used both native and javascript solutions and i think that is the most extensible one and it’s because you can customise it a lot and on v3 is very fast.

Multiple import common problem and absolute paths

As you will see in the next point “Structuring your project” each folder of mine always have a package.json. This package.json have the name of that folder so i can use absolute path in the app.

{
"name": "theme"
}

You can read the David Woody excellent post about it

Also in order to achieve multiple imports in the react native you must use this babel.config.js because other wise you must import them one by one as the babel + metro have compiler errors.

module.exports = {
presets: ['module:metro-react-native-babel-preset'],
plugins: [
[
'@babel/plugin-transform-modules-commonjs',
{
strictMode: false,
allowTopLevelThis: true,
loose: true,
},
],
],
};

If you are using react-native vector icons this will again fail. A temp fix is to import each explictly from their dist folder.

import FeatherIcon from 'react-native-vector-icons/dist/Feather';

You will also need to define a global type for it

declare module 'react-native-vector-icons/dist/Feather';

Structuring your project

I always think that structuring a project folders is one of the most critical moments because here is the first architectural decision you are making on a project. Of course when it comes to RN if you are already familiar with React you don’t have to change much but again here is what i am suggesting.

Each folder must have an index file that can export all the necessary files so you can have multiple imports on other files. Of course this was not feasible till this year and you had to import each module separately but with the help of babel you can use this trick and you would be able to import like the below.

import { Player, Header } from 'components';

screens: Screens are the container components of our application and the actual screens of the app. It is better to have them on there own so we know which screens we are having and to know also our containers

components: Here you can have all your global components that are being used in your application more than once or is not a screen.

ducks: This folder consists of all our app logic because it holds our redux state. It is named after the ducks modular paradigm for redux which is allowed you to scale your application without any problem. A good article can be found here. Each of my duck consists of the following files and how i use type to those files to bind redux with typescript also mentioned on another article of mine

actions - reducer - selectors - types

Beside those files there is an optional one called epics which is the file that holds all the side effect logic using RxJS. Consider looking at it here.

hooks: All the custom hooks that my app is using

services: (optional) this usually holds the instances of several services — push notifications, google tracker etc

providers: Here i am holding all the functions that are providing data to my application such as API calls.

types: Global types that are required for my app. Usually these are the starter contents on this file to avoid type checking on images.

declare module '*.png';
declare module '*.jpg';

utils: any global util for normalising data or picking an id from an array etc. Here i am splitting it across functions or utils etc.

Navigation: As navigation is a big and important part of your application it requires its own space. Here i am breaking my navigation down screen and stack naming. So if you open one of this files you will either see

export const HOME_SCREEN = 'HOME_SCREEN';orexport const INITIAL_STACK = 'INITIAL_STACK';
export const HOME_STACK = 'HOME_STACK';

These are very useful as you can import them in every part of your application to avoid giving strings to your application that you might change in the future.

You appNavigation creates you component that holds all your navigation connected to redux (or not if you are not using it) and here you can define stacks and screens with the names defined above

const HomeStack = createBottomTabNavigator(
{
[HOME_SCREEN]: Home,
}
);

theme: Is the global theme properties and functionalities i am using for the app. Because i am using CSS in JS this folder usually consists of two files functions and globals. Functions have all the functions for creating flex etc and globals are the colors, spacing etc. E.G

export const flex = css`
flex: 1;
`;

export const flexCenter = css`
align-items: center;
justify-content: center;
`;

assets: not on my screenshot but there is always an assets folder to keep all you local sounds, images, videos etc

App Animations easy and hard way

Animations are very vital to any application. Are the ones that would make your app feel native (of course it is!) and will give a better feeling. But you have to be sure not to shoot your foot because there are libraries you can use, lottie and RN animation API.

Lottie will give you a very easy way to show animations on your application but it can easily drag your system down as you build your stack of screens. This is because each screen goes to the top of the previous one. This way your previous screen is still mounted so if you have two screens that are animating a background lottie animation and you are in the second screens both animations are running. So guess what can happen when there are more and more.

Libraries such as animatable are very handy of course you always have to put useNativeDriver. Facebook done a great post explaining why.

If you think you need something custom then animation API is your only way.

Keep in mind when it comes to animation avoid remote debugging, it will slow down your app and always test on a real device by inspecting frames.

To conclude these are not the ones to take without questioning i am just saying that these are the problems i faced and tips and structure i am using to deal when building an application for both iOS and Android using React Native.

What are the ones you are using? Do you think you found these useful? Let me know you thoughts!

If you like this post, consider hitting clap 👏 and you can always visiting my other articles 🔥

--

--

Writer for

Front-End Developer coding with React, React Native & TypeScript • Tech and startup enthusiast • windsurf amateur #react #reactnative #nodejs 🤘