# Getting Started

Looking for an old documentation? As from now, it lives here: <https://flatlogic.gitbook.io/react-native-starter/v/master/>

### What is React Native Starter?

We love building apps with React Native, because it helps us create high quality products for both major mobile platforms quickly and cost-effectively.

Getting started on a new app just takes too long. Most apps need the same basic building blocks and developer infrastructure, and we are bored of reinventing the wheel time and time again.

This Starter Kit reflects the best practices of React Native development we have discovered while building real-world applications for our customers. It is opinionated about tooling, patterns and development practices. It might not be a one-size-fits-all solution for everyone, but feel free to customize it for your needs, or just take inspiration from it.

More information about React Native Starter and downloads: <https://reactnativestarter.com/>

### What's inside

* Always up-to-date React Native scaffolding
* UI/UX Design from industry experts
* Modular and well-documented structure for application code
* Redux for state management
* React Navigation for simple navigation
* Disk-persisted application state caching
* More than 16 Ready-to-use Pages

### Up and running (mac OS)

**1. Clone and Install**

```bash
# Clone the repo
git clone https://github.com/flatlogic/react-native-starter.git

# Install dependencies
yarn install

# Install native ios modules
cd ios && pod install
```

**2. Open RNS in your simulator**

Then you can start the project by going to the project's folder and running there:

```
yarn start

yarn run:ios
```

or, if you want to open it on Android:

```
yarn run:android
```

## Local images not rendered on iOS 14 physical device for release build

If you don't see images here is the fix that will help you until React Native package didn't add this on their end. Open node\_modules folder and find this file [Libraries/Image/RCTUIImageViewAnimated.m](https://github.com/facebook/react-native/commit/123423c2a9258c9af25ca9bffe1f10c42a176bf3#diff-4cb374ac84cbae493f1b0aba42abb676641833d77dcdd921a648098e510e3053)\
scroll to the line 270 and you'll find this pice of code:

```
- (void)displayLayer:(CALayer *)layer
{
  if (_currentFrame) {
    layer.contentsScale = self.animatedImageScale;
    layer.contents = (__bridge id)_currentFrame.CGImage;
  }
}
```

change it to what you see below. Then restart project and clear cache, you may also try to build on different device.

```
- (void)displayLayer:(CALayer *)layer
{
  if (_currentFrame) {
    layer.contentsScale = self.animatedImageScale;
    layer.contents = (__bridge id)_currentFrame.CGImage;
  } else {
    [super displayLayer:layer];
  }
}
```

### Up and running (Windows)

**1. Clone and Install**

```
# Clone the repo
git clone https://github.com/flatlogic/react-native-starter.git

# Install dependencies
yarn install
```

**2. Look through official guide**

{% embed url="<https://facebook.github.io/react-native/docs/getting-started>" %}

**3. If project is not running correctly**

`unable to load script make sure you are either running a metro server ....`

Go to your `root folder of the project > node_modules > metro-config >src > defaults >blacklist.js`.

Open said file (VS Code, etc) and on the top you will see a var called SharedBlacklist. Change that var from what it is to what attached code says

```
FROM

var sharedBlacklist = [
  /node_modules[/\\]react[/\\]dist[/\\].*/,
  /website\/node_modules\/.*/,
  /heapCapture\/bundle\.js/,
  /.*\/__tests__\/.*/
];

TO

var sharedBlacklist = [
  /node_modules[\/\\]react[\/\\]dist[\/\\].*/,
  /website\/node_modules\/.*/,
  /heapCapture\/bundle\.js/,
  /.*\/__tests__\/.*/
];
```

That's it! Cool, right?

### Build project

&#x20;You can generate a private signing key using `keytool`. On Windows `keytool` must be run from `C:\Program Files\Java\jdkx.x.x_x\bin`.

```
keytool -genkeypair -v -keystore my-upload-key.keystore -alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000
```

#### Setting up Gradle variables

1. Place the `my-upload-key.keystore` file under the `android/app` directory in your project folder.
2. Edit the file `~/.gradle/gradle.properties` or `android/gradle.properties`, and add the following (replace `*****` with the correct keystore password, alias and key password),

```
MYAPP_UPLOAD_STORE_FILE=my-upload-key.keystore
MYAPP_UPLOAD_KEY_ALIAS=my-key-alias
MYAPP_UPLOAD_STORE_PASSWORD=*****
MYAPP_UPLOAD_KEY_PASSWORD=*****
```

These are going to be global Gradle variables, which we can later use in our Gradle config to sign our app.

*Note about security: If you are not keen on storing your passwords in plaintext, and you are running OSX, you can also* [*store your credentials in the Keychain Access app*](https://pilloxa.gitlab.io/posts/safer-passwords-in-gradle/)*. Then you can skip the two last rows in `~/.gradle/gradle.properties`.*

#### Adding signing config to your app's Gradle config

The last configuration step that needs to be done is to setup release builds to be signed using upload key. Edit the file `android/app/build.gradle` in your project folder, and add the signing config,

```
...
android {
    ...
    defaultConfig { ... }
    signingConfigs {
        release {
            if (project.hasProperty('MYAPP_UPLOAD_STORE_FILE')) {
                storeFile file(MYAPP_UPLOAD_STORE_FILE)
                storePassword MYAPP_UPLOAD_STORE_PASSWORD
                keyAlias MYAPP_UPLOAD_KEY_ALIAS
                keyPassword MYAPP_UPLOAD_KEY_PASSWORD
            }
        }
    }
    buildTypes {
        release {
            ...
            signingConfig signingConfigs.release
        }
    }
}
...
```

#### Generating the release APK

Run the following in a terminal:

```
$ cd android
$ ./gradlew assembleRelease
```

Also don't forget to run after you saved .apk file

```
./gradlew clean
```

check out official docs <https://reactnative.dev/docs/signed-apk-android>

### Potential issue free vs full v.

If you cloned free version and started it locally, then bought full version and launched it on the same virtual device you may face the issue with set up, it may be caused by the naming collision, please update you virtual device or start brand new VD and run RNS on the new device.


# Architecture

The Starter Kit architecture is designed to support scalable, modular applications. Built around [Redux](http://redux.js.org/), it makes it simple to reason about your application's state, and as a result to write maintainable, error-free programs.

The architecture is heavily inspired by [Pepperoni App Kit](https://github.com/futurice/pepperoni-app-kit)

### Redux

The application state and state changes are managed by **Redux**, a library that implements a pure, side-effect-free variant of the Facebook [Flux](https://facebook.github.io/flux/) architecture. Redux and Flux prescribe a unidirectional dataflow through your application. To understand Redux, check out this [Cartoon guide by Lin Clark](https://code-cartoons.com/a-cartoon-guide-to-flux-6157355ab207#.4dpmozm9v) (it's great, not a joke!) and [Dan Abramov's Redux course on egghead.io](https://egghead.io/series/getting-started-with-redux).

Redux helps us with synchronous updating of our state, but it doesn't provide an out-of-the-box solution for handling asynchronous actions. The Redux ecosystem has many possible solutions for this problem. In our application, we use the vanilla redux-thunk middleware for simple asynchronous actions, and **redux-loop** to handle more complex asynchronicity.

### Organizing code

#### Components

The `components` directory should contain React Native JSX components, which take their inputs in as `props`. In Flux/Redux parlance the components should be dumb/presentation components, meaning that components should not be `connect()`ed to the redux store directly, but instead used by smart/container components.

The components may be stateful if it makes sense, but do consider externalizing state to the Redux store instead. If the state needs to be persisted, shared by other components, or inspected by a developer in order to understand the program state, it should go in the Redux store.

A component may be either written as an ES6 `class Foo extends Component` class or as a plain JavaScript function component. Usage of `React.createClass` should be avoided, as it [will be deprecated in 15.5](https://github.com/facebook/react/issues/8854)

If a component implementation differs between iOS and Android versions of the application, [create separate `.android.js`and `.ios.js` files](https://facebook.github.io/react-native/docs/platform-specific-code.html) for the component. In minor cases the `React.Platform.OS` property can be used to branch between platforms.

#### Modules

The `modules` directory contains most of the interesting bits of the application. As a rule of thumb, this is where all code that modifies that application state or reads it from the store should go.

Each module is its own directory and represents a "discrete domain" within the application. There is no hard and fast rule on how to split your application into modules (in fact, this is one of the most difficult decisions in designing a Redux application), but here are some qualities of a good module:

* Represents a screen in the application, or a collection of screens that form a feature.
* Represents some technical feature that needs its own state (e.g. `navigator`).
* Rarely needs to use data from other modules' states.
* Doesn't contain data that is often needed by other modules.

**Anatomy of a Module**

At its simplest, a module contains three logical part: **State**, **View(s)** and **Container(s)**. All of these are optional, i.e. a component may or may not a have a View. If a module consists only of a View, though, do consider making it a component instead.

**State**

The **State** contains the state of the application, and any actions that can modify that state. State can be data, for example fetched from a server or created by the user in-app, or it may be something transient, such as whether the user is logged into the application, or whether a particular UI element should be displayed or not.

The State part of the module is a [Redux Duck](https://github.com/erikras/ducks-modular-redux) - a file that contains a Reducer, Action Creators and the initial state of the application.

Let's take a simple example of an application that displays a number, which the user can increment by pressing a *plus* button, and decrement using a *minus* button.

{% code title="CounterState.js" %}

```javascript
// INITIAL STATE
//
// We start by defining the initial state for this module.

const initialState = {
  value: 0
};

// ACTION TYPES (Naming: SCREAMING_CASE)
//
// Let's define constants for the action types. The action types must be globally unique,
// so we namespace them with a prefix to avoid accidental collisions. It also helps to make
// the action name descriptive, as it helps with debugging. In most cases the action constants
// will be private to the State file, but in some advanced scenarios may be exported

const UPDATE_NUMBER = 'CounterState/UPDATE_NUMBER';

// ACTION CREATORS (Naming: camelCase)
//
// Action creators are functions whose responsibility is to encapsulate the creation of the
// messages passed to the reducer. Their API should be consumer-friendly and hide as much of
// the internal implementation of the state update as possible.
//
// At their simplest Action creators just construct a Flux Standard Action -compliant action.
// Other times they may call asynchronous services and rely on a Redux middleware.
//
// Action creators are always named exports, `export function name() {...}`, or `export const name = ...`

export function increment() {
  return { type: UPDATE_NUMBER, payload: +1 };
}

export function decrement() {
  return { type: UPDATE_NUMBER, payload: -1 };
}

// REDUCER (Naming: PascalCase)
//
// Reducer is responsible for handling all the actions defined in this module. The first
// parameter is the previous state of this module, and should default to the initial state.
//
// The reducer then examines the `action` object and decides whether any state should change in
// response to that action. The reducer must return the updated state, or if no changes are made,
// the previous state without modifications.
//
// The reducer is always an ES6 default export.

export default function CounterStateReducer(state = initialState, action) {
  switch (action.type) {
    case UPDATE_NUMBER:
      return state.update('value', value => value + action.payload);
    default:
      return state;
  }
}
```

{% endcode %}

The Redux Ducks pattern aims to keep the code portable, contained and easy to refactor by co-locating the reducer with action creators. For complex modules, the Duck can get quite long and make it difficult to maintain, in which case it should be split into smaller chunks, either by separating the reducer into its own file or by splitting the state into smaller Ducks and combining the reducers using standard Redux split/combine strategies.

**View**

Typically the **View** represents the screen in the application. A module may have multiple views, if the part of the application consists of multiple screens, or if the single view is too complex to write in a single file.

Technically speaking the View is identical to a component we define in the `components` directory. The difference is the way we use them. Ideally, the View's role is to orchestrate reusable components. The view can be aware of what the application state looks like and which actions update it, whereas a component should not `dispatch` things directly, and have their `props` API designed around the purpose of the component, not the state of the application.

The View usually has some presentational components and styling, but usually the leaner the view the better. If a view implementation needs to be very different on iOS and Android, separate `.android.js` and `ios.js` files may be written. However, for maintainability purposes, it is better if the platform-specific implementation can be done on `component` level, and the View can remain platform-agnostic.

A View should take all inputs as `props`, and should very, very rarely, if ever, be stateful. Instead, the state should be managed in Redux, and injected to the component props by the container.

To continue the Counter example, a view might look something like this:

{% code title="CounterView\.js" %}

```javascript
import React, {StyleSheet, Text, View} from 'react-native';
import PropTypes from 'prop-types';
import ActionButton from '../../components/ActionButton';
import * as CounterState from './CounterState';

class CounterView extends Component {
  // state (value) and action dispatcher are provided as props
  static propTypes: {
    value: PropTypes.number.isRequired,
    dispatch: PropTypes.func.isRequired
  },

  render() {
    const {value, dispatch} = this.props;
    // use reusable components (ActionButton) to dispatch actions created by CounterState action creators
    return (
      <View style={styles.container}>
        <Text style={styles.counter}>{value}</Text>
        <ActionButton onPress={() => dispatch(CounterState.increment())} text='+' />
        <ActionButton onPress={() => dispatch(CounterState.decrement())} text='-' />
      </View>
    );
  }
});

// styles are defined inline
const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
    alignItems: 'center',
    backgroundColor: 'white'
  },
  counter: {
    textAlign: 'center',
    fontSize: 40
  }
});

export default CounterView;
```

{% endcode %}

**Container**

The **Container** (or **View Container**) is responsible for `connect()`ing the View component to the Redux store.

Also, the Container is responsible for using the High Order functions with [recompose](https://github.com/acdlite/recompose).

Redux `connect()` takes in two arguments, first `mapStateToProps` which selects relevant parts of the application state to pass to the view, and second `mapActionsToProps`, which binds Action Creators to the store's dispatcher so the actions are executed in the right context. These functions are often called *selectors*.

We think using `mapStateToProps` is a good practice, but avoid using `mapActionsToProps` in favour of calling `dispatch`ourselves in the view. In our experience this leads to simpler, easier to reason about code (and a little less verbose PropTypes on the View).

Every time the app state changes, the Container is automatically called with the latest state. If the props returned by the container differ from the previous props, the connected View is re-rendered. If the props are identical, the view is not re-rendered.&#x20;

Using the Counter example, the container would be very simple:

{% code title="CounterContainer.js" %}

```
import {connect} from 'react-redux';
import CounterView from './CounterView';

// pass the counter's value to the component as a prop called `value`.
// Because we omit the second parameter, the `dispatch` function is
// automatically passed as a prop.
export default connect(
  state => ({
    value: state.getIn(['counter', 'value'])
  })
)(CounterView);

```

{% endcode %}

Often this file doesn't contain a lot of code, but it's important to define the Container in its own file anyway to be able to support platform-specific view implementations, as well as test the Views and their data bindings separately.

If a View needs data from other modules (i.e. other parts of the application state than the subtree managed by that module), the Container is the correct place to access. In database-speak, this way you can keep your data "normalized" (to a degree), and "join" them when required.


# Testing

This part describes, how you can improve your app's stability with different testing tools

## Unit Testing

The first and the most popular option is unit-testing of your JavaScript modules. React Native Starter comes with ready-to-use Jest integration, which you can use to test components, classes and functions.

Let's talk about testing each of them.

### Testing Views

The best way to test if your views are rendered correctly is to create a view snapshot and compare the new snapshots each time. This way you can see when your views are changing or not.

Let's pretend you have a button component that can take a string or an image as a children component and calls onPress handler when TouchableOpacity inside this component is clicked. So your button component looks something like this:

{% code title="components/Button.js" %}

```javascript
export const Button = ({ children, onPress }) => (
  <View style={styles.container}>
    <TouchableOpacity onPress={onPress}>
      {children}
    </TouchableOpacity>
  </View>
);
```

{% endcode %}

And what you want to test here are that:

1. Button renders correctly with image and with a text.
2. `onPress`handler is fired when TouchableOpacity has been pressed.

Let's create a test file called `Button.spec.js`. By default, jest looks for all the files named as `*.spec.js`, `*.test.js` and for files placed under the `__tests__` folder.

{% code title="components/Button.spec.js" %}

```javascript
import React from 'react';
// Import enzyme's shallow renderer
import { shallow } from 'enzyme';

// Describes a test group
describe('Button', () => {
  it('renders correctly with a text', () => {
    // Render our button with a text inside
    const wrapper = shallow(<Button>test</Button>);

    // Check that the rendered button matches
    // previously saved snapshot
    expect(wrapper).toMatchSnapshot();
  });

  it('renders correctly with an image', () => {
    // Render our button with an image inside
    const wrapper = shallow(
      <Button>
        <Image src={require('something')} />
      </Button>,
    );

    // Check that the rendered button matches
    // previously saved snapshot
    expect(wrapper).toMatchSnapshot();
  });

  it('handles onPress', () => {
    // Create a mock function to pass as a handler
    const onPress = jest.fn();

    // Render our button with an image inside
    const wrapper = shallow(<Button onPress={onPress}>test</Button>);

    // Find a TouchableOpacity and press it
    wrapper
      .find('TouchableOpacity')
      .first()
      .props()
      .onPress();

    // Check that our handler have been called 1 time
    expect(onPress).toHaveBeenCalledTimes(1);
  });
});

```

{% endcode %}

Learn more about Unit-testing here: <https://jestjs.io/docs/en/tutorial-react-native>

## End to end testing

We integrated **Detox** framework for running end2end tests for your app. We also integrated it with jest, so you can write your tests in the familiar environment.

High velocity native mobile development requires us to adopt continuous integration workflows, which means our reliance on manual QA has to drop significantly. Detox tests your mobile app while it's running in a real device/simulator, interacting with it just like a real user.

The most difficult part of automated testing on mobile is the tip of the testing pyramid - E2E. The core problem with E2E tests is flakiness - tests are usually not deterministic. We believe the only way to tackle flakiness head on is by moving from black box testing to gray box testing. That's where Detox comes into play.

* **Cross Platform:** Write cross-platform tests in JavaScript. Currently supports iOS, Android is nearly complete. View the [Android status page](https://github.com/wix/Detox/blob/master/docs/More.AndroidSupportStatus.md).
* **Runs on Devices** (not yet supported on iOS): Gain confidence to ship by testing your app on a device/simulator just like a real user.
* **Automatically Synchronized:** Stops flakiness at the core by monitoring asynchronous operations in your app.
* **Made For CI:** Execute your E2E tests on CI platforms like Travis without grief.
* **Test Runner Independent:** Use Mocha, AVA, or any other JavaScript test runner you like.
* **Debuggable:** Modern async-await API allows breakpoints in asynchronous tests to work as expected.

Let's pretend you want to test your that your login flow works and verify it with Detox.

First, create a file called `login.spec.js` under the `e2e` folder and add the following code there:

{% code title="e2e/login.spec.js" %}

```javascript
describe('Login flow', () => {
  it('should login successfully', async () => {
    await device.reloadReactNative();
    await expect(element(by.id('email'))).toBeVisible();
      
    await element(by.id('email')).typeText('john@example.com');
    await element(by.id('password')).typeText('123456');
    await element(by.text('Login')).tap();
      
    await expect(element(by.text('Welcome'))).toBeVisible();
    await expect(element(by.id('email'))).toNotExist();
  });
});

```

{% endcode %}

&#x20;Then, simply open your console and type

```bash
e2e:build && e2e:test
```

That's it! You should see the iOS simulator opened and your app tested.


# Internationalization

We understand that your users can speak many different languages, so we've included an internalization support into the React Native Starter. It's done with the help of <https://github.com/react-native-community/react-native-localize> and <https://github.com/fnando/i18n-js>.

All the translations files live under the `src/translations` folder. Translation for each language are placed inside the json files with locale names.

### Adding a new language

In order to add a new language you need to do 3 simple steps. Let's imagine you're adding a support for German language :

1. Create a file called `src/translations/de.json` and add translations strings there (see below for explanation on translation strings).
2. Change the `src/translations/index.js` to be the following

{% code title="src/translations/index.js" %}

```javascript
import * as RNLocalize from 'react-native-localize';
import i18n from 'i18n-js';

import en from './en.json';
import ru from './ru.json';

// Import newly added language file
import de from './de.json';

// Add the German translation to the list
const translations = { en, ru, de };

const { languageTag } = RNLocalize.findBestAvailableLanguage(
  Object.keys(translations),
) || { languageTag: 'en' };

i18n.locale = languageTag;
i18n.fallbacks = true;
i18n.translations = translations;

export default i18n;
```

{% endcode %}

And now you can use translations in your files.

### Using Translated Strings

First of all, let's see, how to define translations string in translation files. Look at the example translation file:

{% code title="src/translations/en.json" %}

```javascript
{
  "Common": {
    "minutes": "Minutes",
    "days": "Days",
    "button": {
      "save": "SAVE",
      "cancel": "CANCEL",
    },
    "done": "Done",
  },
  "Settings": {
    "audio": "Audio Enabled?"
  }
}
```

{% endcode %}

In such file you define your translated strings as a nested JSON.

After you defined your translations, you can use it anywhere in your code like this:

{% code title="src/settings/SettingsSection.js" %}

```javascript
// ... All the imports

// Import from your translations index
import I18t from '../translations';

export default function SettingsSection() {
  return (
    <View>
      <Text>{I18t.t('Settings.audio')}</Text>
      <Button>{I18t.t('Settings.Common.button.save')}</Button>
    </View>
  );
}
```

{% endcode %}

Call to `I18t.t('PATH')` will return the translated string for the current user language from json file with a path, equal to `PATH`&#x20;

For more information, refer to <https://github.com/react-native-community/react-native-localize> documentation.


# Adding Pages and Components

RNS comes with predefined set of components and screens, but we sure you'd love to add your own! And we've tried to make it as simple as possible for you with a help of plop generator: <https://plopjs.com/>

We our predefined plop templates you can generate 3 different features for your app:

1. A component.
2. A stateless module.
3. A stateful module.

Let's talk about each of them.

### Adding new Components

As described in [Arhitecture](/arhitecture#components), components are stateless (usually), reusable react elements. They are placed under the `src/components` folder and simply exports an element from the js file.

So, basically, creating a new component is just:

1. Create a new file under `components` folder.
2. Create a react element inside the newly created file and export it as a default.
3. Create a spec file for writing tests.

And we automated this steps with a single command. Open your terminal and type.

```
plop component MyButton
```

This command will:

1. Create an `src/components/MyButton/index.js` file.
2. And add the following content inside:

{% code title="src/components/MyButton/index.js" %}

```javascript
// @flow
import React from 'react';
import {
  View,
} from 'react-native';

import { colors } from '../styles';

type Props = {}

export default (props: Props) => (
  <View />
);

const styles = StyleSheet.create({});
```

{% endcode %}

&#x20;   3\.  Create a spec file called `src/components/MyButton/index.spec.js`  with the following content:

{% code title="src/components/MyButton/index.spec.js" %}

```
/* eslint-disable no-undef */
import React from 'react';
import { shallow } from 'enzyme';

import {
  MyButton,
} from '../index';

describe('{{properCase name }} Component', () => {
  it('renders as expected', () => {
  const wrapper = shallow(
    <MyButton />,
  );
  expect(wrapper).toMatchSnapshot();
});
```

{% endcode %}

### Adding a new Module

Have a loot at what's module in our [Arhitecture](/arhitecture#modules) documentation.

To create a new module, simply run this command in your console:

```
plop module CalendarScreen
```

Then, plop will ask you to if you want statefull or stateless module.

1. Statefull module has connection to redux store.
2. Stateless doesn't :)

After you making your choice, the generator will:

1. Create a new folder under `modules` called `calendarScreen`&#x20;
2. Add a new file called `CalendarScreenView.js` with a sample view for the new screen.
3. Add a new file `CalendarScreenViewContainer.js` with a connection calendar view to the redux (if you picked a statefull component) and wrapping it with recompose.
4. If your component is statefull, it will create `CalendarScreenState.js` file and fill it with redux-related code (described in Architecture as well).
5. For statefull components, your screen will be imported into the redux store.

Have a look at example files content:

{% tabs %}
{% tab title="src/modules/calendarScreen/CalendarScreenState.js" %}

```javascript
// @flow
type CalendarScreenStateType = {};

type ActionType = {
  type: string,
  payload?: any,
};

export const initialState: CalendarScreenStateType = {};

export const ACTION = 'CalendarScreenState/ACTION';

export function actionCreator(): ActionType {
  return {
    type: ACTION,
  };
}

export default function CalendarScreenStateReducer(state: {{properCase name }}StateType = initialState, action: ActionType): {{properCase name }}StateType {
  switch (action.type) {
    case ACTION:
      return {
        ...state,
      };
    default:
      return state;
  }
}

```

{% endtab %}

{% tab title="src/modules/calendarScreen/CalendarScreenView\.js" %}

```javascript
// @flow
import React from 'react';
import {
  View,
  Text,
} from 'react-native-ui-lib';

type Props = {};

export default (props: Props) => (
  <View flex centerV centerH>
    <Text>CalendarScreen View</Text>
  </View>
);
```

{% endtab %}

{% tab title="src/modules/calendarScreen/CalendarScreenViewContainer.js" %}

```javascript
// @flow
import { compose } from 'recompose';
import { connect } from 'react-redux';

import CalendarScreenView from './{{properCase name }}View';

export default compose(
  connect(
    state => ({}),
    dispatch => ({}),
  ),
)(CalendarScreenView);
```

{% endtab %}
{% endtabs %}

Further documentation on Plop could be found on <https://plopjs.com/>


# Components

Components are stateless rect elements. They render what you pass to them and call function as callbacks. Components are essential part of the app. Here's the list of available components:

### Button

![](/files/-LK6KnUw8uKH_De1KavM)

Regular Button can be rendered like this:

```javascript
<Button
  style={styles.demoButton}
  primary
  caption="Button"
  onPress={this.buttonClicked}
/>
```

Button component takes the following props:

| Prop name         | Type     | Description                         |
| ----------------- | -------- | ----------------------------------- |
| `primary`�        | boolean  | Make button BG primary colored      |
| `secondary`       | boolean  | Make button BG secondary colored    |
| `bordered`        | boolean  | Button without bg, but with borders |
| `rounded`         | boolean  | Adds border radius to componen      |
| `small`           | boolean  | Renders small button                |
| `icon`            |          | Icon for the button                 |
| `caption`         | string   | Button's label                      |
| `onPress`         | function | onPress handler                     |
| `bgColor`         | string   | Background color                    |
| `textColor`       | string   | Text color                          |
| `bgGradientStart` | string   | Color of gradient bg start          |
| `bgGradientEnd`   | string   | Color of gradient bg end            |
| `action`          | boolean  | Renders action button               |
| `loading`         | boolean  | Renders loading indicator           |

### Radio Group

Renders a tab-style radio group.

![](/files/-LK6M4NzgKRL0gpPT8da)

Can be rendered:

```javascript
<RadioGroup
  style={styles.demoItem}
  items={['One', 'Two', 'Three']}
  selectedIndex={props.radioGroupsState[0]}
  onChange={index => props.setRadioGroupsState({ ...props.radioGroupsState, 0: index })}
/>
```

Component's props:

| Prop name       | Type           | Description                                    |
| --------------- | -------------- | ---------------------------------------------- |
| `items`         | array\[string] | Items to render on the Radio button            |
| `secondary`     | boolean        | Renders secondary-styles radio group           |
| `rounded`       | boolean        | Renders radio group with rounded corners       |
| `underline`     | boolean        | Renders underline-styled radio button          |
| `onChange`      | function       | Called when the button in the group is clicked |
| `selectedIndex` | number         | Index of selected item                         |

### Dropdown

![](/files/-LK6MpKBFSEdLQWGZJlL)

Use the dropdown this way:

```javascript
<Dropdown
  onSelect={() => {}}
  items={['option 1', 'option 2']}
/>
```

Dropdown's props:

| Prop name  | Type           | Description                                     |
| ---------- | -------------- | ----------------------------------------------- |
| `onSelect` | function       | Callback that called after the item is selected |
| `items`    | array\[string] | Items for the dropdown                          |


# Text

Text component provides a simple element to avoid dealing with sizing in the React Native Text.

![](/files/-MGxElGp5DDWI-NgT7fX)

```jsx
import { Text } from '../components/';

<Text component="h1">Default text</Text>
<Text component="h2">Default text</Text>
<Text component="h3">Default text</Text>
<Text component="h4">Default text</Text>
<Text component="h5">Default text</Text>
<Text component="h6">Default text</Text>
<Text component="s1">Default text</Text>
<Text component="s2">Default text</Text>
<Text component="p1">Default text</Text>
<Text component="p2">Default text</Text>
<Text component="c1">Default text</Text>
<Text component="c2">Default text</Text>
<Text component="label">Default text</Text>
```

## Properties

| Name         | Type                                   | Description                                                                                                                                                                                                                                                                                                                                             |
| ------------ | -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| children     | `ReactText \| ReactElement<TextProps>` | String or number to be rendered as text. Also can be ReactElement - nested Text component.                                                                                                                                                                                                                                                              |
| component    | `string`                               | Can be `h1`, `h2`, `h3`, `h4`, `h5`, `h6`, `s1`, `s2`, `p1`, `p2`, `c1`, `c2`, `label`. Defaults to *p1*. Use *h* categories when needed to display headings. Use *s* categories when needed to display subtitles. Use *p* categories when needed to display regular text. Use *c* and *label* categories when needed to give user a hint on something. |
| ...TextProps | `TextProps`                            | Any props applied to Text component.                                                                                                                                                                                                                                                                                                                    |


# Icon

![](/files/-MGxFb4FK_XSTXJGuliv)

Icon component provides a simple way to render images by requesting it from an icon set.

```jsx
import Icon from 'react-native-vector-icons/MaterialCommunityIcons';
import { colors } from '../../styles';

<Icon name={'home'} size={24} color={colors.primary} />
<Icon name={'calendar'} size={24} color={colors.primary} />
<Icon name={'apps'} size={24} color={colors.primary} />
<Icon name={'layers'} size={24} color={colors.primary} />
<Icon name={'widgets'} size={24} color={colors.primary} />
<Icon name={'clipboard-text'} size={24} color={colors.primary} />
```

## Properties

| Name     | Type     | Description                                     |
| -------- | -------- | ----------------------------------------------- |
| name     | `string` | A name of icon registered in a specific pack.   |
| size     | `int`    | Size of the icon                                |
| color    | `string` | Color of the icon                               |
| ...props | `any`    | Accepts any props available in a specific pack. |


# Card

Cards contain content and actions about a single subject.

![](/files/-MGxFyu-Tmew2qW7Z4NL)

\
In basic example, card accepts content view as child element.

```jsx
import { Card } from '../components';

<Card>
      <Text>Today we are going to provide you with excellent articles to read in December. Enjoy fresh ideas, tips, and tricks from the JavaScript world.</Text>
</Card>
```

It also may have header and footer by configuring `header` ,`description` ,`footer` properties.

```jsx
import { Card } from '../components';

<Card title={"Title"} description={"Description"} footer={<View style={styles.footerContainer}><Button style={{marginRight: 10, flex: 1}} caption={"Cancel"} bordered primary /><Button primary caption={"Apply"} style={{flex: 1}} /></View>}>
      <Text>Today we are going to provide you with excellent articles to read in December. Enjoy fresh ideas, tips, and tricks from the JavaScript world.</Text>
</Card>
```

## Properties

| Name        | Type                          | Description                                       |
| ----------- | ----------------------------- | ------------------------------------------------- |
| children    | `ReactNode`                   | Component to render within the card.              |
| title       | `(ViewProps) => ReactElement` | Function component to render above the content.   |
| description | `(ViewProps) => ReactElement` | Function component to render description content. |
| footer      | `(ViewProps) => ReactElement` | Function component to render footer content.      |


# List

Performant interface for rendering simple, flat lists.&#x20;

Lists should render ListItem components by providing them through `renderItem` property to provide a useful component.

```jsx
import { FlatList } from 'react-native';
import { List, ListItem } from '../components'

const DATA = [
  {
    id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
    title: 'First Item',
  },
  {
    id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
    title: 'Second Item',
  },
  {
    id: '58694a0f-3da1-471f-bd96-145571e29d72',
    title: 'Third Item',
  },
];

const renderItem = ({ item }) => (
    <List>
      <ListItem title={item.title} />
    </List>
);


<FlatList
        data={DATA}
        renderItem={renderItem}
        keyExtractor={item => item.id}
/>
```

Using ListItem is helpful for basic lists, but not required. For example, `Card` may be used.

```jsx
import { FlatList } from 'react-native';
import { List, ListItem, Card } from '../components'

const DATA = [
  {
    id: 'bd7acbea-c1b1-46c2-aed5-3ad53abb28ba',
    title: 'First Item',
    content: 'Today we are going to provide you with excellent articles to read in December. Enjoy fresh ideas, tips, and tricks from the JavaScript world.',
  },
  {
    id: '3ac68afc-c605-48d3-a4f8-fbd91aa97f63',
    title: 'Second Item',
    content: 'Today we are going to provide you with excellent articles to read in December. Enjoy fresh ideas, tips, and tricks from the JavaScript world.',
  },
  {
    id: '58694a0f-3da1-471f-bd96-145571e29d72',
    title: 'Third Item',
    content: 'Today we are going to provide you with excellent articles to read in December. Enjoy fresh ideas, tips, and tricks from the JavaScript world.',
  },
];

const renderItem = ({ item }) => (
    <List>
      <ListItem>
        <Card title={item.title}>{item.content}</Card>
      </ListItem>
    </List>
);


<FlatList
    data={DATA}
    renderItem={renderItem}
    keyExtractor={item => item.id}
/>
```

## Properties

| Name             | Type                                   | Description                                             |
| ---------------- | -------------------------------------- | ------------------------------------------------------- |
| data             | `array`                                | An array of anything to be rendered within the list     |
| renderItem       | `(ListRenderItemInfo) => ReactElement` | Takes an item from *data* and renders it into the list. |
| ...FlatListProps | `FlatListProps`                        | Any props applied to FlatList component.                |


# Top Navigation

TopNavigation provides a heading component for the entire page.

![](/files/-MGxGTRZXs5MV4FttG_f)

In basic example TopNavigation contains a title and actions.

```jsx
    <TopNavigation>
          <Image source={topNavArrow} height={20} style={{position: "absolute", left: 0}}/>
          <View style={{ justifyContent: 'center' }}>
              <Text style={styles.topNavTitle}>Title</Text>
          </View>
    </TopNavigation>
```

TopNavigation may contain the right action on the left.

```jsx
    <TopNavigation>
          <View style={{ justifyContent: 'center' }}>
              <Text style={styles.topNavTitle}>Title</Text>
          </View>
          <Image
              source={topNavContextMenu}
              style={{ height: 20, position: "absolute", right: 0 }}
            />
    </TopNavigation>
```

## Properties

| Name           | Type                                       | Description                                                                                                                 |
| -------------- | ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------- |
| title          | `ReactText \| (TextProps) => ReactElement` | String, number or a function component to render within the top navigation. If it is a function, expected to return a Text. |
| subtitle       | `ReactText \| (TextProps) => ReactElement` | String, number or a function component to render within the top navigation. If it is a function, expected to return a Text. |
| accessoryLeft  | `() => ReactElement`                       | Function component to render to the left edge the top navigation.                                                           |
| accessoryRight | `() => ReactElement`                       | Function component to render to the right edge the top navigation.                                                          |
| ...ViewProps   | `ViewProps`                                | Any props applied to View component.                                                                                        |


# Top Tabs

Top Bar provides top navigation.

```jsx
 import { RadioGroup } from '../components'
 
 <View>
   <RadioGroup
      items={items}
      selectedIndex={tab1State}
      onChange={index => setTab1State(index)}
      underline
    />
    <Text>{items[tab1State]}</Text>
</View>
```

Tabs also may contain `icons`, to provide a better user interfaces.

```jsx
  import { RadioGroup } from '../components'
  
  <View>
   <RadioGroup
      items={[
              <View
                style={{
                  alignItems: 'center',
                  flexDirection: 'row',
                  color: 'inherit',
                }}
              >
                <Text style={{ color: 'inherit' }}>One</Text>
                <Icon name={'staro'} size={20} style={{ marginLeft: 5 }} />
              </View>,
              <View
                style={{
                  alignItems: 'center',
                  flexDirection: 'row',
                  color: 'inherit',
                }}
              >
                <Text>Two</Text>
                <Icon name={'staro'} size={20} style={{ marginLeft: 5 }} />
              </View>,
              <View
                style={{
                  alignItems: 'center',
                  flexDirection: 'row',
                  color: 'inherit',
                }}
              >
                <Text>Three</Text>
                <Icon name={'staro'} size={20} style={{ marginLeft: 5 }} />
              </View>,
            ]}
      selectedIndex={tab1State}
      onChange={index => setTab1State(index)}
      underline
    />
    <Text>{items[tab1State]}</Text>
</View>
```


# Bottom Tabs

Bottom Tabs provides bottom navigation.

```jsx
 import { RadioGroup } from '../components'
 
 <RadioGroup
    items={items}
    selectedIndex={tab1State}
    onChange={index => setTab1State(index)}
    topUnderline
 />
```

Tabs also may contain `icons`, to provide a better user interfaces

```jsx
import { RadioGroup } from '../components'
 
 <RadioGroup
    items={[
        <Icon name={'staro'} size={20} />,
        <Icon name={'staro'} size={20} />,
        <Icon name={'staro'} size={20} />,
    ]}
    selectedIndex={tab1State}
    onChange={index => setTab1State(index)}
    topUnderline
 />
```


# Menu

A versatile menu for navigation.

```jsx
import { Divider, Menu } from '../components'

<Menu 
    items={['Item 1', 'Item 2', 'Item 3']}
/>
```

Menu also may contain `icons`, to provide a better user interfaces.

```jsx
import { Divider, Menu } from '../components'

<Menu 
    items={[<View
                style={{
                  alignItems: 'center',
                  flexDirection: 'row',
                  color: 'inherit',
                }}
              >
                <Text style={{ color: 'inherit' }}>One</Text>
                <Icon name={'staro'} size={20} style={{ marginLeft: 5 }} />
              </View>,
              <View
                style={{
                  alignItems: 'center',
                  flexDirection: 'row',
                  color: 'inherit',
                }}
              >
                <Text>Two</Text>
                <Icon name={'staro'} size={20} style={{ marginLeft: 5 }} />
              </View>,
              <View
                style={{
                  alignItems: 'center',
                  flexDirection: 'row',
                  color: 'inherit',
                }}
              >
                <Text>Three</Text>
                <Icon name={'staro'} size={20} style={{ marginLeft: 5 }} />
              </View>,}]
/>
```


# Button

Buttons allow users to take actions, and make choices, with a single tap.<br>

Default button size is `medium` and status color is `primary`.

```jsx
import { Button } from '../components'

<Button
   style={styles.demoButton}
   primary
   caption="Button"
   onPress={() => {}}
/>
```

Button can be disabled with `disabled` property.

```jsx
import { Button } from '../components'

<Button
   style={styles.demoButton}
   primary
   disabled
   caption="Button"
   onPress={() => {}}
/>
```

Button can be styled with `rounded`, `bordered` properties.

```jsx
import { Button } from '../components'

<Button
   style={styles.demoButton}
   primary
   rounded
   caption="Button"
   onPress={() => {}}
/>

<Button
   style={styles.demoButton}
   primary
   bordered
   caption="Button"
   onPress={() => {}}
/>

<Button
   style={styles.demoButton}
   primary
   rounded
   bordered
   caption="Button"
   onPress={() => {}}
/>
```

Button can be used with icon.

```jsx
import { Button } from '../components'

<Button
   style={styles.demoButton}
   primary
   rounded
   icon={<Icon />}
   caption="Button"
   onPress={() => {}}
/>
```

Buttons can be resized by using `sm`, `md`, `lg` property.

```jsx
import { Button } from '../components'

<Button
   style={styles.demoButton}
   primary
   sm
   icon={<Icon />}
   caption="Button"
   onPress={() => {}}
/>

<Button
   style={styles.demoButton}
   primary
   icon={<Icon />}
   caption="Button"
   onPress={() => {}}
/>

<Button
   style={styles.demoButton}
   primary
   lg
   icon={<Icon />}
   caption="Button"
   onPress={() => {}}
/>
```

You can specify background-color properties.

```jsx
import { Button } from '../components'
import { colors } from '../../styles';

<Button
   style={styles.demoButton}
   bgColor={colors.green}
   icon={<Icon />}
   caption="Button"
   onPress={() => {}}
/>

<Button
   style={styles.demoButton}
   primary
   icon={<Icon />}
   caption="Button"
   onPress={() => {}}
/>

<Button
   style={styles.demoButton}
   secondary
   icon={<Icon />}
   caption="Button"
   onPress={() => {}}
/>
```


# Checkbox

Checkboxes allow the user to select one or more items from a set.

```jsx
import { Checkbox } from '../components'

<Checkbox 
  status={'checked'}
  onPress={(state) => !state}
  color={colors.primary}
/>
```

CheckBoxes can be checked or disabled.

```jsx
import { Checkbox } from '../components'

<Checkbox 
  status={'unchecked'}
  onPress={(state) => !state}
  color={colors.primary}
  disabled
/>
```

## Properties

| Name     | Type                       | Description                                    |
| -------- | -------------------------- | ---------------------------------------------- |
| status   | `string`                   | Can be `checked`, `unchecked`                  |
| onPress  | `(status: string) => void` | Called when checkbox should switch it's value. |
| color    | `string`                   | Changes a color of the checkbox.               |
| disabled | `bool`                     | Makes the checkbox disabled.                   |


# Toggle

Switches toggle the state of a single setting on or off.

```jsx
import { Checkbox } from '../components'

<Switch value={val} onValueChange={(val) => !val} />
```

## Properties

| Name          | Type                | Description                                        |
| ------------- | ------------------- | -------------------------------------------------- |
| value         | `bool`              | Whether component is checked. Defaults to *false*. |
| onValueChange | `(boolean) => void` | Called when toggle should switch it's value.       |
| disabled      | `bool`              | Makes toggle disabled.                             |


# Input

Inputs let users enter and edit text.

![](/files/-MGxGqRQ5Z7LOUAmCEzq)

```jsx
import { Input } from '../components'

<Input
    placeholder={'Place your Text'}
/>
```

Input can be dark on the bright screen.

```jsx
import { Input } from '../components'

<Input
    dark
    placeholder={'Place your Text'}
/>
```

Input can be disabled:

```jsx
import { Input } from '../components/'

<Input
    disabled
    placeholder={'Place your Text'}
/>
```

You can make input bordered:

```jsx
import { Input } from '../components/'

<Input
    type="bordered"
    placeholder={'Place your Text'}
/>
```

You can make the input with a caption:

```jsx
import { Input } from '../components/'

<Input
    caption="Simple caption text"
    placeholder={'Place your Text'}
/>
```

You can make the input with a label:

```jsx
import { Input } from '../components/'

<Input
    label="Simple label text"
    placeholder={'Place your Text'}
/>
```

## Properties

| Name        | Type                                       | Description                                                                                                             |
| ----------- | ------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------- |
| placeholder | `string`                                   | A string to be displayed when there is no value.                                                                        |
| dark        | `bool`                                     | Makes input dark.                                                                                                       |
| disabled    | `bool`                                     | Makes input disabled.                                                                                                   |
| label       | `ReactText \| (TextProps) => ReactElement` | String, number or a function component to render above the input field. If it is a function, expected to return a Text. |
| caption     | `ReactText \| (TextProps) => ReactElement` | String, number or a function component to render below the input field. If it is a function, expected to return a Text. |
| value       | `string`                                   | A value displayed in input field.                                                                                       |


# Screens

### Description

Screens are place inside `src/screens`  folder and they render the complete UI for any part of your project. Screens are simply receiving props from outside and render the data. Here's the list of awailable screens:

### Calendar

Allows you to build a customisable calendar with events. Built around <https://github.com/wix/react-native-calendars>

<div align="left"><img src="/files/-LK6GQgz5CfsILWnP5tV" alt="Calendar Screen"></div>

### Grids

We have 3 grid styles available. This screens are receiving data from props and render in a way you choose. You can choose from 3 different styles:

1. Simple bricks

![](/files/-LK6HFmlsRoyCe33QaJT)

2\. One-line grid

![](/files/-LK6HMwp5VhA6o0B5Fuk)

3\. One-line informative grid

![](/files/-LK6HRD5RAJ6p4Vn784F)

### Product page

Product page is a page for describing any goods you want to sell. It has an image slider, picker, description.

![](/files/-LK6H_2Ftl0XxwkuCmIE)

### Charts

Our charts are customisable  and built based on <https://github.com/FormidableLabs/victory-native>

![](/files/-LK6IEFcyK6kSfYLldUE)

### Gallery

Screen for displaying images in instagram-style

![](/files/-LK6IN3elikwJyrgDD9g)

### User profile

Displays the profile info, social link, etc.

![](/files/-LK6JBjqFA5CGIpPRYdo)

### Chat and messages

You can build you own messaging system based on this screens.

![](/files/-LK6JQSrNZRZcNzW8vKn)

![](/files/-LK6JTlDXTGAqVdhLB-c)

### Login/Registration screen

![](/files/-LK6Ja8VNYrKcWLaxlZS)


# Theming

There are a few pre-built themes available in React Native Starter. To enable any particular theme, go to the project's directory and run the command in console for the selected theme.

### &#x20;Classic Blue

To activate this theme, run in the project's root folder:

```
$THEME_NAME=blue bash ./change-theme.sh
```

![](/files/-LfJkbwPgdMNTIV0MxH0)

### Classic Red

To activate this theme, run in the project's root folder:

```
$THEME_NAME=red bash ./change-theme.sh
```

![](/files/-LfJkn-EsV2ZLfxWyflm)

### Dark

To activate this theme, run in the project's root folder:

```
$THEME_NAME=dark bash ./change-theme.sh    
```

![](/files/-LfJkzFXvGTLUHRyxb0c)

### Fancy

To activate this theme, run in the project's root folder:

```
$THEME_NAME=fancy bash ./change-theme.sh    
```

![](/files/-LfJlB4c96DcWqi_L_lv)

### Material

To activate this theme, run in the project's root folder:

```
$THEME_NAME=material bash ./change-theme.sh    
```

![](/files/-LfJlMbD-VRxfh9-ZXOX)

### Classic

To activate this theme, run in the project's root folder:

```
$THEME_NAME=classic bash ./change-theme.sh    
```

![](/files/-LfJZ_Us-Ypl8bqZ9t3c)


# Getting Started

#### What is React Native Starter?

We love building apps with React Native, because it helps us create high quality products for both major mobile platforms quickly and cost-effectively.

Getting started on a new app just takes too long. Most apps need the same basic building blocks and developer infrastructure, and we are bored of reinventing the wheel time and time again.

This Starter Kit reflects the best practices of React Native development we have discovered while building real-world applications for our customers. It is opinionated about tooling, patterns and development practices. It might not be a one-size-fits-all solution for everyone, but feel free to customize it for your needs, or just take inspiration from it.

More information about React Native Starter and downloads: <https://reactnativestarter.com/>

### What's inside

* Always up-to-date React Native and Expo scaffolding
* UI/UX Design from industry experts
* Modular and well-documented structure for application code
* Redux for state management
* React Navigation for simple navigation
* Disk-persisted application state caching
* More than 16 Ready-to-use Pages

### Up and running

**1. Clone and Install**

```bash
# Clone the repo
git clone https://github.com/flatlogic/react-native-starter.git

# Install dependencies
yarn install
```

**2. Open RNS with Expo**

First, you need to install Expo CLI (if you don't have it yet). You can do it by running the following command in terminal:

```
npm install expo-cli --global
```

Then you can start the project by going to the project's folder and running there:

```
expo start
```

That's it! Cool, right?


# Architecture

The Starter Kit architecture is designed to support scalable, modular applications. Built around [Redux](http://redux.js.org/), it makes it simple to reason about your application's state, and as a result to write maintainable, error-free programs.

### Redux

The application state and state changes are managed by **Redux**, a library that implements a pure, side-effect-free variant of the Facebook [Flux](https://facebook.github.io/flux/) architecture. Redux and Flux prescribe a unidirectional dataflow through your application. To understand Redux, check out this [Cartoon guide by Lin Clark](https://code-cartoons.com/a-cartoon-guide-to-flux-6157355ab207#.4dpmozm9v) (it's great, not a joke!) and [Dan Abramov's Redux course on egghead.io](https://egghead.io/series/getting-started-with-redux).

Redux helps us with synchronous updating of our state, but it doesn't provide an out-of-the-box solution for handling asynchronous actions. The Redux ecosystem has many possible solutions for this problem. In our application, we use the vanilla redux-thunk middleware for simple asynchronous actions, and **redux-loop** to handle more complex asynchronicity.

### Organising code

#### Components

The `components` directory should contain React Native JSX components, which take their inputs in as `props`. In Flux/Redux parlance the components should be dumb/presentation components, meaning that components should not be `connect()`ed to the redux store directly, but instead used by smart/container components.

The components may be stateful if it makes sense, but do consider externalising state to the Redux store instead. If the state needs to be persisted, shared by other components, or inspected by a developer in order to understand the program state, it should go in the Redux store.

A component may be either written as an ES6 `class Foo extends Component` class or as a plain JavaScript function component. Usage of `React.createClass` should be avoided, as it [will be deprecated in 15.5](https://github.com/facebook/react/issues/8854)

If a component implementation differs between iOS and Android versions of the application, [create separate `.android.js`and `.ios.js` files](https://facebook.github.io/react-native/docs/platform-specific-code.html) for the component. In minor cases the `React.Platform.OS` property can be used to branch between platforms.

#### Containers

The **Container** (or **View Container**) is responsible for `connect()`ing the View component to the Redux store.

Redux `connect()` takes in two arguments, first `mapStateToProps` which selects relevant parts of the application state to pass to the view, and second `mapActionsToProps`, which binds Action Creators to the store's dispatcher so the actions are executed in the right context. These functions are often called *selectors*.

We think using `mapStateToProps` is a good practice, but avoid using `mapActionsToProps` in favour of calling `dispatch`ourselves in the view. In our experience this leads to simpler, easier to reason about code (and a little less verbose PropTypes on the View).

We also use  `recompose` to give you an ability to manage state, lifecycle events and more inside your containers, not components. Check you the docs at <https://github.com/acdlite/recompose>


# Screens

### Description

Screens are place inside `src/screens`  folder and they render the complete UI for any part of your project. Screens are simply receiving props from outside and render the data. Here's the list of awailable screens:

### Calendar

Allows you to build a customisable calendar with events. Built around <https://github.com/wix/react-native-calendars>

<div align="left"><img src="/files/-LK6GQgz5CfsILWnP5tV" alt="Calendar Screen"></div>

### Grids

We have 3 grid styles available. This screens are receiving data from props and render in a way you choose. You can choose from 3 different styles:

1. Simple bricks

![](/files/-LK6HFmlsRoyCe33QaJT)

2\. One-line grid

![](/files/-LK6HMwp5VhA6o0B5Fuk)

3\. One-line informative grid

![](/files/-LK6HRD5RAJ6p4Vn784F)

### Product page

Product page is a page for describing any goods you want to sell. It has an image slider, picker, description.

![](/files/-LK6H_2Ftl0XxwkuCmIE)

### Charts

Our charts are customisable  and built based on <https://github.com/FormidableLabs/victory-native>

![](/files/-LK6IEFcyK6kSfYLldUE)

### Gallery

Screen for displaying images in instagram-style

![](/files/-LK6IN3elikwJyrgDD9g)

### User profile

Displays the profile info, social link, etc.

![](/files/-LK6JBjqFA5CGIpPRYdo)

### Chat and messages

You can build you own messaging system based on this screens.

![](/files/-LK6JQSrNZRZcNzW8vKn)

![](/files/-LK6JTlDXTGAqVdhLB-c)

### Login/Registration screen

![](/files/-LK6Ja8VNYrKcWLaxlZS)


# Components

Components are stateless rect elements. They render what you pass to them and call function as callbacks. Components are essential part of the app. Here's the list of available components:

### Button

![](/files/-LK6KnUw8uKH_De1KavM)

Regular Button can be rendered like this:

```javascript
<Button
  style={styles.demoButton}
  primary
  caption="Button"
  onPress={this.buttonClicked}
/>
```

Button component takes the following props:

| Prop name         | Type     | Description                         |
| ----------------- | -------- | ----------------------------------- |
| `primary`�        | boolean  | Make button BG primary colored      |
| `secondary`       | boolean  | Make button BG secondary colored    |
| `bordered`        | boolean  | Button without bg, but with borders |
| `rounded`         | boolean  | Adds border radius to componen      |
| `small`           | boolean  | Renders small button                |
| `icon`            |          | Icon for the button                 |
| `caption`         | string   | Button's label                      |
| `onPress`         | function | onPress handler                     |
| `bgColor`         | string   | Background color                    |
| `textColor`       | string   | Text color                          |
| `bgGradientStart` | string   | Color of gradient bg start          |
| `bgGradientEnd`   | string   | Color of gradient bg end            |
| `action`          | boolean  | Renders action button               |
| `loading`         | boolean  | Renders loading indicator           |

### Radio Group

Renders a tab-style radio group.

![](/files/-LK6M4NzgKRL0gpPT8da)

Can be rendered:

```javascript
<RadioGroup
  style={styles.demoItem}
  items={['One', 'Two', 'Three']}
  selectedIndex={props.radioGroupsState[0]}
  onChange={index => props.setRadioGroupsState({ ...props.radioGroupsState, 0: index })}
/>
```

Component's props:

| Prop name       | Type           | Description                                    |
| --------------- | -------------- | ---------------------------------------------- |
| `items`         | array\[string] | Items to render on the Radio button            |
| `secondary`     | boolean        | Renders secondary-styles radio group           |
| `rounded`       | boolean        | Renders radio group with rounded corners       |
| `underline`     | boolean        | Renders underline-styled radio button          |
| `onChange`      | function       | Called when the button in the group is clicked |
| `selectedIndex` | number         | Index of selected item                         |

### Dropdown

![](/files/-LK6MpKBFSEdLQWGZJlL)

Use the dropdown this way:

```javascript
<Dropdown
  onSelect={() => {}}
  items={['option 1', 'option 2']}
/>
```

Dropdown's props:

| Prop name  | Type           | Description                                     |
| ---------- | -------------- | ----------------------------------------------- |
| `onSelect` | function       | Callback that called after the item is selected |
| `items`    | array\[string] | Items for the dropdown                          |


