Author
Federico Ojeda
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.
Base tooling
As you may be well aware of, React Native uses Javascript
, so we can use the 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.
Axios
for networking.PropTypes
to type-check components’ exposed properties.React-Native-Config
to manage environments.React-Native-Navigation
as native navigation library.React-Native-Localization
for string localization.Redux
for state management.Recompose
for utilities.Redux-Persist
as persistence layer.Redux-Thunk
to dispatch asynchronous actions.Reselect
the selector library for redux.Jest and Enzyme
for testing.
Architecture
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.
Folder Structure
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.
- MyComponent.js
- styles.js
- Index.js
- 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.
State Management
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.
Navigation
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.
Networking
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!
Persistence
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 Redux
’s store.
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.
Standards
As in any larger project, following a consistent coding standard helps improve the quality of the overall software. Javascript’s ecosystem has some wonderful tools to enforce several guidelines. We went with 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 .eslintrc.json
file.
Testing
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
and Enzyme
.
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.
Configuration
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
npm
package react-native name - Run the following command in the root of the project:
react-native-rename <newName>
- Bingo! The project’s been renamed with the new name
- Push it to the repository
Wrapping Up
At Moove It we 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. We feel is our responsibility, as a React Native Development Company, to share our knowledge and help those who are just beginning to use this technology.
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!