React Native is taking over the mobile world, from the very start of being released to the general public. Being a newcomer in the industry, there isn’t a proper consensus for the structure of a React Native based app, so we’ve decided to implement our own.
A main reason we want to define a baseline for a new project is to reduce the number of decisions a developer has to make before developing a new project. Based on our previous experiences in several other applications, we have defined a project template that works as a starting point for React Native projects, providing a base architecture, a core framework, and helpers to jumpstart your development.
Here, we introduce the fundamental concepts and tools included in the project. To just view the code, you can skip to our Github repository and access the template directly.
As you may be well aware of, React Native uses
NPM (Node Package Manager) ecosystem and all the libraries/frameworks that it provides. The following list includes all the basic packages that come pre-installed in the project with their purposes. Most are explained later below, too.
PropTypesto type-check components’ exposed properties.
React-Native-Configto manage environments.
React-Native-Navigationas native navigation library.
React-Native-Localizationfor string localization.
Reduxfor state management.
Redux-Persistas persistence layer.
Redux-Thunkto dispatch asynchronous actions.
Reselectthe selector library for redux.
Jest and Enzymefor testing.
Container – Presentation
Even though not defined explicitly in the template, and being more of a team decision, we prefer to structure our components following the container-presentation pattern.
For those not familiar with this, a container-presentation pattern consists of dividing your components into two types – container and presentation. Container components manage logical state and any logic involved (such as data fetching). The presentation components are exclusively responsible for the UI.
This can bring a lot of advantages in terms of reusability and separation of responsibilities. To delve further into this, check how to structure the components and why containers are useful. These posts explain with much more detail.
Having an organized folder structure is probably the most important facet in a JS based application. Here are more defined guidelines on how to use this structure with the files and folders.
- src: This folder is the main container of all code inside the application.
- actions: This folder contains all actions that can be dispatched to redux.
- assets: Asset folder to store all images, vectors, etc.
- components: Folder that contains all application components.
- Common: Folder to store any common component that you use through app (such as a generic button, text fields, etc).
- MyComponent: Each component should be stored inside its own folder, and inside it a file for its code and a separate one for styles. The index.js is used only to export the final component that will be used on the app.
- helpers: Folder to store any kind of helper you may have.
- reducers: This folder should have all your reducers and expose the combined result using its index.js
- selectors: Folder to store your selectors for each reducer.
- controllers: Folder to store all network and storage logic (you should have one controller per resource).
- App.js: Main component that starts the app.
- index.js: Entry point of your application as per React-Native standards.
As most agree,
Redux is a great option to handle the state of a
React (native or not) application and rightfully so. It’s popular, widely used, full of support, and provides a clean way to store in-memory data.
But, like every other framework,
Redux has its caveats. If used incorrectly, you can end up having too much boilerplate code, which is confusing and makes the code base just messy. You can review the source code of the template and see how we solved these issues.
In order to perform navigations between screens, we went with
react-native-navigation. It’s a native library, so all navigation is done on the native side. This is why it is extremely fast and performant. Also, it has an amazing API that’s intuitive and integrated with
Redux. Creating custom navigations is a bit tricky, and react-native-navigation is probably the best, most neat solution we have found till date.
There is no application on the market that doesn’t use a network request. Every app generally needs to make a request through the internet. Finding a correct library for making HTTP calls is important. We use
Axios, and we love it, since it has huge support and popularity in the community. It also provides a lot of cool helpers & features that just make life easier!
It’s really common storing some data, starting from a small token to having multiple entities with complex relationships amongst them. This is why we needed a solution for this recurrent situation.
For simpler cases, such as saving a token or smaller pieces of data, we use
Redux-Persist. It’s a library that’s built on top of
Redux, and provides a clear, almost transparent way of saving the information that’s inside
Whenever a more powerful tool to express a complex relationship, or for transactional operations over data is needed, we are definitely in favor of using
Realm. It’s a robust and powerful database that provides a simple SDK to create, maintain and operate databases on mobile devices.
ESLint, the default library in the JS ecosystem.
About the rules, we didn’t want to reinvent the wheel so to speak, so we use
ESLint rules made by Airbnb, based on their style guide. Some exceptions were made to these rules, which you can see in the
No app should be coded without testing. That’s why, from the beginning, our team began developing this template, with a mindset of a testing environment to be implemented, a priority really. There are too many possibilities, but we liked most the combination of
Jest provides a truly complete testing platform for React that requires really a small amount of configuration, and
Enzyme allows us to perform tests over the DOM elements that are rendered and ensure that certain aspects of the UI are carried out.
To best manage the configuration, we are using
react-native-config to handle all important configurations in one central place.
How to use it
There are two options to set up a new project using the template:
Option 1: Copy the files
This is the easier option, where you copy everything under the /src and the index.js folders into a new react-native project. Naturally, dependencies are defined on the package.json file, so you can copy them to the dependencies of the newly created package.json.
Option 2: Use react-native-rename
- Clone this repository to your machine.
- Change the git project remote URL to one of your own with
git remote set-url origin https://github.com/USERNAME/REPOSITORY.git
- Install the
npmpackage react-native name
- Run the following command in the root of the project:
- Bingo! The project’s been renamed with the new name
- Push it to the repository
We at Moove It have defined a starting point for any React Native project possible. Having a standard and base for any project is always an advantage, both for developers starting work, as well as for the newcomer diving into an existing project. React Native can get complicated for those with no experience.
It’s always easier to step into a project knowing where everything is, which frameworks are being used, and other basic development information. New technologies like this can have a chaotic start with a lot of future changes. This template provides a big advantage and a lot of stability!
One question we asked ourselves while building this was if we can use this for any type of software project. The answer is yes, hands down! One of our main goals is to keep this template as small and flexible as possible, completely user friendly. We hope it can be used in as many cases as possible. And we see it happening, we hope it helps you too!