Starting from the ground up? We'll look at the structure of the boilerplate code. An opinionated way to build apps, inspired by several apps in production.
It is highly recommended that you go through the Storyboarding lesson before moving ahead with this one.
The course comes with an open source boilerplate code that has been built using TypeScript, with the most commonly-needed tools already set up. It has been based on the official React Native Getting Started docs (1) and instructions from Microsoft's GitHub TypeScript React Native Starter (2) repo. This will help us jumpstart building apps using React Native.
The boilerplate has been build using industry standard tools that have been tested over multiple apps in production. Some of the salient features of the boilerplate app include:
Routing and navigation
Tabbed navigation using React Native Navigation v7 (3)
Side menu support
State management using the Flux architecture
Widgets and elements - build your own design system with these building blocks.
<CText>. They are custom elements that have default properties like font, size and so on.
widgets: Any component providing a complete functionality, e.g. carousel component, banner component, etc.
Base typography setup has been taken care of: Color, Font, LAYOUT, CTA, FONTS, TEXT, TEXT_INPUT. Modify this as per needs of the app.
Airbnb's JS linting (6)
Before we jump into actually running the boilerplate app in the next section, here we will look at the project structure and learn how to navigate it.
index.js at the root location is the entry point of the application. We initialize our navigator and set the app's default navigation type: single screen vs tabbed. We also need to register the screens that will be used in the app.
The application has further been divided into two main folders, based on responsibility:
src This is the presentation layer of the app; screens, styles, images, icons etc.
shared Everything related to the application logic is here. The Redux store, service integrations and any API calls.
Below, you can find the application structure defined in detail. Try not to get overwhelmed by it! My suggestion would be to just skim through it once, and keep this as a reference and come back to it as and when required. It can also act as a great frame of reference when adding something to the app, like for e.g. where to add a new service, or API calls, constants, globals and so on.
configGlobal configuration needed to bootstrap the app, like API endpoints, default locale, deeplinks etc.
RouterThis is the application router. All routing methods should be defined here along with props.
NavigationThe base navigation of the app has been defined here. Tabbed, single screen, or drawer-based.
elementsThe smallest building blocks of the app, like custom texts and primary / secondary buttons.
assetsImages, SVGs and more. It is always good practice to have sub-folders grouped by section.
screensAll the screens that will be built for the app. The styles of the screens are also kept along with the screens, as they will be accessed mostly while in development and do not merge with other stylesheets, unlike a web application.
stylesGlobal styles and colors are defined here. This constitutes the design system of the app and we should try to build this first, before writing any additional styles in the app.
widgetsPlaceholder for the components to be written for the app.
constantsThe constants relating to the application's business logic, like action types.
actionsThe methods for actions are declared here. They map methods to action types.
apiThis will be a one-stop-shop for all the API calls made from the application. It will expose the standard GET, POST and other methods, as required. This is also a good place to define any additional headers etc needed before making an API call.
reducersThe reducers are defined here.
storeThe application store is initialized here. This is a good place for adding middlewares, like for analytics or logging.
thunkSingle place for business logic for dispatchers called from views.
serviceAdd low-level services and third-party integrations here. AsyncStorage is a good example of a service that can be added here. Analytics is another example. It is good practice to keep them here as this keeps them separate from the core application logic. If, for example, tomorrow the plan is to switch from Google Analytics to Branch.io, you could keep the methods' signatures the same and simply update the implementation.
typesThe types are declared here.