Modern React Native projects- from start to finish.

Ismael Bakkali
guidesmiths
Published in
6 min readSep 23, 2019
Photo by David Pisnoy on Unsplash

Have you ever wondered how to strive for better react-native development and how to overcome the common problems that 90% of apps present? If so, keep reading to find out about procedures and working with a startup…

After almost a year of dealing with React projects, I’ve seen common mistaken patterns, situations where code becomes legacy and a lack of core principles.

The most valuable reason I learned is to always look for better developer experience. At the end of the day, the main goal of the software is to solve problems, however, I do believe that the transition from one status (incomplete) to another (complete) plays an essential role. Our work feeling has to be prioritized, no one likes to work in a messy space or uncomfortable chair, no one likes spending hours trying to understand a code written from somebody else, no one wants to feel pressure delivering but no one talks about it.

I found that instead of throwing away the technology used, I could use my experience to talk about different approaches and tools.

Sometimes we perform actions because that’s what everyone does or even because someone “says so” without any hesitation, which can lead to some of the problems below that I’ve seen in modern React projects:

⁃ Component API not defined

⁃ Same language different versions around

⁃ Over-engineering with a global state management

⁃ Needless test

⁃ Lack of core principles

⁃ Folder structure not very intuitive

⁃ Naming convention not defined

⁃ Multiple lint rules

⁃ No code style standard, not even used prettier 😕

⁃ Utils maniac, everything goes there

⁃ Obsessive using third party libraries

⁃ No PRs, dead code and of course duplications

⁃ Really nested relative paths

Let’s keep in mind

There is no software nirvana, BUT

there is a better dev experience always.

To solve these problems I started to ask myself how I could both enjoy coding and produce an awesome outcome at the same time. Rules. Any society is based on rules — otherwise, we will act chaotically without any common understanding. The same thing happens when developing. Rules are some sort of language we all understand, no more no less. Rules could of course change over time and it’s perfectly fine- but it’s good to know where we stand at the time.

That’s where prettier comes so handy for code style. Love it.

Here’s my one:

.prettierrc

The second sample will apply a linter to analyse code errors and warnings etc…

Here’s the es-lint config I’ve used:

https://gist.github.com/ismaelocaramelo/386a5705beb666f0ee785014d749ebf4

So no more style errors, code formatting no matter what you have installed on your IDE we WILL follow the rules.

Of course, we should have something automated before committing. Husky and lint stage in da house.

Here’s how it looks like:

https://gist.github.com/ismaelocaramelo/98f3421dcb6f6b34b93966f4ce1b1b4d

For nested relatives paths the solution was to apply the concept as react does. Adding package name to each folder.

https://gist.github.com/ismaelocaramelo/b4bd358c37d5fa7292bb17e7481f69da

Let’s talk about what really bothers me and excites at the same time. Component architecture

My advice is focused on having an open component API at the beginning and you will fly at the end

Keep in mind we are looking to enhance dev exp. through making decisions which we felt right in the first place.

Based on that, my mental model relied on a modular components approach. Here’s the deal: when we create a generic component we are making it hard for us to use, to understand what actually represents and of course to decoupled.

A component should just do one thing and do it well.

That’s obvious if you buy a t-shirt, you are not buying a generic T-shirt and then apply changes to it yourself (at least 90% of the cases). You’re taking exactly what you need, size, colour, etc. Yeah, we are getting closer!

How to architect a component?

- Fewer inputs

- Keep it composable

- Style as implementation details

-Name convention

Keeping the style as implementation details will allow you to cherry-pick what you need on each UI. So UI component can be updated or refactored without affecting anything else in the application. Any style on the usage will be considered a code smell.

To make it composable I found very useful patterns like render props and compound components which enhance the simplicity and expressiveness of the whole matter. Essentially applying inversion of control, letting the user decide what to render.

Fewer inputs, just the essential data to full fill the component’s responsibility.

And finally, I’d like to name my components basically with two concepts. Context + Responsibility and purpose

  • Context, where the components live in. E.g Dashboard
  • Responsibility and purpose. E.g DashboardTooltip

Here’s some sort of implementation of all of this:

https://gist.github.com/ismaelocaramelo/707fd75a1881a8e3717180951636c3b2

What about state management?

This is one topic that catches the attention of many developers. Ok,

I survive without Redux

I’m not against Redux: I still think it’s a powerful tool, but it has been misunderstood and overused. What I really like is the conceptual model of describing immutable updates with pure functions.

Now that we have Context, a first-class citizen and React hooks, I can combine the two and have beautiful mini-states management.

I’ve used Context for global stuff like user details and cross shared “static” elements. Applying the core concept to some components is fairly simple with React.useReducer, you can manage the state locally so you do not need some convoluted-top-store management. A reducer doesn’t have to be attached to a global store. The idea behind this is to reduce the scope of a reducer, to help you avoid the need for passing callbacks, and of course to express the different states of a component.

To persist data I’ve used AsyncStorage from RN library.

By the way, if you’d like to learn more about Redux principles you can have a look at my presentation https://slides.com/ismaelbakkali/deck.

Procedures

How many times are you excited when something new comes out? So am I.. It happened to me with react hooks. But we should ask ourselves what is the problem that new tool solves.

From a business point of view, it doesn’t really matter as long as the final product is there. So why I should be embracing an overhead when the result probably would be the same. Even though, we as developers love new stuff. That’s incomprehensible between the two worlds. Here’s the trick, a business should care about developer experience and developers should care about the product itself. This is based on the religious commandment ‘You will love your neighbour as yourself’.

Working with a no agile company/startup/no-idea-of-what-we-want is quite an interesting challenge. One of the things I regret is not having direct communication with the product owner. Instead, we communicated with their technical staff with some sort of management role.

So we wipe out our agile ecosystem to dovetail in their procedures. That’s the first mistake.

Sometimes we felt like machines without purpose, coding then became a solution for an issue instead of the big-picture solution. We as developers need to understand why and what will be the impact of doing whatever is requested.

From a startup perspective, the performance time of creating a new feature depends on the last feature time delivered and not the feature itself. Of course, we all want to get the client’s confidence in the first place.

So faster delivery lead to code with timing No matter what for everyone. That’s the second mistake

What about setting the developer himself some objectives to hit? Everyone has their own piece and not even the same timing. We are all learners but of course, we should deliver on time. But it seems the opposite right?. That’s because a feature has a preset delivery time. A feature should have some intern limit time, it’s the whole team who is responsible for that, not the client.

So a feature shouldn’t have a responsible, but a team. The timing should preserve on the team, not on client. Pairing should be a must. That’s the third mistake

Overall here’s the list of lessons I learned:

1. Engaging with the product and the code will not be meaningless.

2. Do not pressure yourself to deliver faster at the beginning

3. Have direct conversions with the Product Owner without intermediates

4. Pairing is a must, do not be a cowboy

5. Take time to look properly at PRs

6. Have a continuous refactoring mind

I’m a software developer at Guidesmiths. I mainly work on mobile apps using react-native. I hope it helps. :)

--

--