This project is a React Native mobile application.
The driving goal of the architecture is separation of concerns. Namely:
-
Presentational components are separated from containers (aka "screens").
Presentational components are small components that are concerned with how things look. Containers usually define whole application screens and are concerned with how things work: they include presentational components and wire everything together.
If you are interested you can read more about it here.
-
State is managed using global Redux stores.
When applications grow, sharing state and its changes can become very hard. Questions like "How can I access this data?" or "When did this change?" are common, just like passing data around components just to be able to use it in nested components.
With Redux, state is shared using global stores, and changes are predictable: actions are applied by reducers to the state. While the pattern can be a bit much for small projects, the clear separation of responsibilities and predictability helps with bigger applications.
If you are interested you can read more about it here.
-
Application side-effects (API calls, etc.) are separated from UI and state manipulation using Redux Saga.
Using Redux Saga has two benefits: keeping application side-effects and related business logic out of UI components, as well as executing that logic in an asynchronous way without ending in callback hell.
Sagas are triggered by Redux actions and can also trigger Redux actions to alter state. By using JavaScript generators (
yield
), sagas are written in a synchronous-like manner while still executing asynchronously.
The project contains:
- a React Native application (in "ejected" mode to allow using dependencies that rely on native code)
- a clear directory layout to provide a base architecture for your application
- Redux to help manage state
- Redux Persist to persist the Redux state
- Redux Sagas to separate side-effects and logic from state and UI logic
- React Navigation with a
NavigationService
to handle routing and navigation in the app, with a splash screen setup by default - reduxsauce to facilitate using Redux (with stable .d.ts)
- axios to make API calls
- prettier and eslint preconfigured for React Native
App/Components
: presentational componentsApp/Config
: configuration of the applicationApp/Containers
: container components, i.e. the application's screensApp/Assets
: assets (image, audio files, ...) used by the applicationApp/Navigators
: react navigation navigatorsApp/Sagas
: redux sagasApp/Services
: application services, e.g. API clientsApp/Stores
: redux actions, reducers and storesApp/Theme
: base styles for the application
For more information on each directory, click the link and read the directory's README.
Node 8 or greater is required. Development for iOS requires a Mac and Xcode 9 or up, and will target iOS 9 and up.
You also need to install the dependencies required by React Native:
- for Android development
- for iOS development
Assuming you have all the requirements installed, you can setup and run the project by running:
yarn install
to install the dependencies- create your configuration file
App/Config/index.ts
fromindex.dev.ts
(in you are in dev environment) and fill the missing values - run the following steps for your platform
- only the first time you run the project, you need to generate a debug key with :
cd android/app
keytool -genkey -v -keystore debug.keystore -storepass android -alias androiddebugkey -keypass android -keyalg RSA -keysize 2048 -validity 10000
cd ../..
to come back to the root folder
react-native run-android
to run the Android application (remember to start a simulator or connect an Android phone)
cd ios
pod install
to install pod dependenciescd ..
to come back to the root folderyarn start
to start the metro bundler, in a dedicated terminalreact-native run-ios
to run the iOS application (remember to start a simulator or connect an iPhone phone)
- Using Fastlane to automate builds and store deployments (iOS and Android)
- You may want to use CocoaPods to manage your dependencies (iOS only)