Structuring a Team for a Big React Native App

React Native

React Native seems to have taken the mobile hybrid world by storm providing a native app result using web development technologies.

A Big React Native App

A big React Native app would have many screens and sub-screens, lots of actions and reducers, and significant interaction with a server-side or cloud API.

Structuring the Team

One can consider organizing the development team along two major dimensions:

  • Vertical - along screens - each developer takes responsibility for the screen, the logic, the actions, the reducers, and the API calls

  • Horizontal - across layers - one developer ( a group of developers) specializes in the rendering and styling, maybe also in the component-specific login, a second developer (group) in the actions and reduces, while a third developer (group) concentrates on the API calls.

The problem is compounded when remote teams are to be used.

Our Experience in Team Organization

We have developed a big React Native app with several remote teams. We observed early on that a horizontal division is better.

This is the fact that different skills and knowledge are required for each layer. Development of each layer interacts mainly with different groups within the enterprise. Such interaction requires specific tools.

Rendering

Good rendering requires a keen visual sense and attention to visual detail. Extensive knowledge of React Native rendering and CSS is needed. Such a group of developers would use Zeplin or similar to consume the graphic assets and UI specs. They would need close interaction with the UI and graphic design group is needed.

Logic

The logic of a big app involves component-specific logic and state management.

Using Redux terminology, but equally applicable to other state management approaches such as MobX, the logic development group will develop around the state representation: actions, selectors, and reducers.

Such logic and state development require close interaction with the product management group of the enterprise. The tools to be used for interaction usually documents. Good knowledge of ES 2017 capabilities, such as arrow functions, the spread operator, and similar is needed.

API Access Layer

Accessing the server side API for fetch and update is focused on making HTTP calls, using fetch or a similar library. It requires expertise in efficient server-side calls, such as structuring HTTP headers, and authorization mechanisms such as JWT.

The API access group works in close interaction with the server side group of the enterprise.

Why Horizontal?

Given that different skills, domains of knowledge, tools, and interactions are needed in each of the layers of the app, a horizontal division lets you organize your team around the expertise of the developers. Each developers group specializes in one domain of skills and knowledge. Such specialized developers are much easier to find. Each group uses a particular set of tools and interacts mainly with one particular group of the whole enterprise. The interaction pattern is thereby a one-to-one.

In contrast, a vertical division requires a multi-talent developer, which is much harder to find. Moreover, the interaction with the rest of the enterprise becomes a many-to-many interaction. A much harder collaboration pattern is needed.

Horizontal Team Organisation

Advocating a horizontal division of work across a team requires these groups of developers:

  1. Rendering

  2. Logic and state

  3. API access

  4. Integration

While we have described above the first three groups, the later one was not mentioned. The integration groups do the creation of the app, defines the navigation structure, say with React Navigation, and structures the file organization.

Structuring a React Native APP for a Team

The React Native app structure has to allow for such a team organization otherwise it would not work.

Splitting the files along with folders such as (e.g. when using Redux):

  1. components

  2. containers

  3. actions

  4. Selectors

  5. reducers

  6. API

is just the beginning. The logic resides in many places and is developed by one group.

But, if you follow good React development practices and make components functional, the rendering group can concentrate on working with mock data,

const ReservationItem = ({reservation, navigation, mode}) => {}

With the logic group providing the actual computation.

Just Functional Components Would Not Fly

It is all fine to think in terms of pure functional components, but they would not fly for two reasons:

  1. Internal state is needed

  2. Activating the actual actions and subsequently the API access layer on lifecycle events and user actions

We have developed a two-pronged solution:

  1. Recompose for adding internal state and action activation, using withState, lifecycle mainly.

  2. Full components when the functional notation became a parenthesis hell

In both cases, the rendering group will work with mock data, in one of two ways:

  1. Local data at the top of the component file,

    let posts = [{}, {}, ...]
    
  2. Pulling the initial state of the store which is mocked.

When the Logic Comes In

The logic group takes each functional component in turn and replaces the mock data with real data from the store. Along the way, it adds real action calls in lifecycle methods and in onPress handlers.

When the API Comes In

The API group will often write reshaping functions to integrate with the logic, as an API is in a flux, or not fully known to the logic group. Of course, you need to provide some idea of how it looks to the rendering group. But our experience has shown that working from a Zeplin UI design, the rendering group can work by guessing the JSON structure.