loading...
Cover image for Transitioning from React Native to Flutter
IT Minds

Transitioning from React Native to Flutter

magnusjensen95 profile image Magnus Jensen ・5 min read

A few months ago, my company was offered an assignment based on a from-scratch Flutter app, and the task was eventually sent my way. At the time, I had been working a React Native project for ~ 18 months, so no real Flutter development experience here.

What I want to accomplish with this post, is to give the reader some insight into the process of transitioning from a world of Javascript (and / or Typescript) and coming to the strongly typed domain of the Dart language and the UI stallion that is Flutter.

Initially I want to mention that there is actually a pretty hands-on walkthrough that goes through many Flutter features from the point of view of a React Native developer. This can be found here. It has enough to get one through an initial screening interview so definitely worth a look.

This post assumes some knowledge of React and Javascript but not necessarily about Dart or Flutter.

The early days

You may find yourself in this spot right now. It's time to dig into at new language and a new framework.

The big challenge for me was to adapt both the dart language and Flutter at the same time. At times it was cumbersome to tell the two apart. Also, a big challenge was to identify eligible knowledge from TS and React Native that could be utilized 1:1 in Dart and Flutter.

In my arrogance I started out by booting up a Flutter project from the CLI, and tried to get my hands dirty (you're an app developer right?). So many questions. The default Flutter project is filled with default code and comments attached to it. Which is fine... If you understand it. I tried to make my go-to application:

  • Load list of Pokémon
  • Display said list.

Super simple stuff! However, coming from a world of Typescript where type safety is more of a reminder/guideline, in Dart (as in any actual strongly typed language) you get the stick if you do not behave and type your stuff appropriately.

Suddenly, mapping a network response to a typed Dart model was the challenge of a lifetime.

After grinding through a tutorial on FIRST the Dart language and then Flutter, things started to lighten up.

Architectural choices

When you have a decently sound understanding of the core foundations of Dart and Flutter, you are ready to get started on the development process.

In terms of architectural patterns in Flutter, there are many. I came from an architecture build-up with redux as the state management library, and so the flux pattern was very familiar to me in terms of how to mutate the state and have it consumed by your components (widgets in Flutter).

State management was a tough nut to crack, simply because of the many options available. An overview of state management option in Flutter can be found in their own documentation.

How to choose then?

Our project needed to utilize a firebase backend with authentication flowing through here as well. It wasn't going to be the biggest Flutter project of our time, so we thought a lightweight framework would suit our needs. To us, that meant going with the GetX package.

This is a simple package that can be tailored to handle state management, routing and dependency management.

The last of these might seem tempting if you are new to Flutter.

If we take a look at a barebone stateless widget in Flutter (just like a regular function component in React):

class SomeWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(

    );
  }
}
Enter fullscreen mode Exit fullscreen mode

The BuildContext argument to the build method has a ton of functionality attached to it, and to some degree it plays a role in everything we want to do with our app (i.e. manage state, navigate, get theme colors, localization, you name it).

It can however be a nuisance to pass around to the functions and classes that need a reference to it.

This is where the GetX package "shines" if you will. It basically "removes" the need for it, as long as you use functions pulled from that package.

There were a lot of quoting in that statement, as it is of course not the whole truth, the dependency injection is just mitigated by the package methods. Their own documentation mentions that it seems magical.

So why disregard this?

As handy as it seemed, it also felt like a fundamental anti-pattern to disregard the use of contexts entirely. And given that there was no real experience with Flutter within our team, it just eventually seemed like a bad idea.

One Wednesday I approached my coworker and asked if it would be cool if we rewrote 70 % ish of the code we had written. It was such a large portion, as we had baked the package into every eligible area of the codebase possible, and it suddenly seemed that the entire application was 100 % coupled to the functionalities of a single 3rd party library. Not what we wanted. And if we ever wanted to move away from this, it would just not be possible due to the lack of standard dependency injection being used.

Enter the Bloc package

I consulted a friend of a friend, who luckily is a lot smarter than I. He recommended the Bloc package as a solid foundation for our application.

The package itself only facilitates the state management of the app, but the documentation provides an excellent example of a scaling architecture that is easily maintainable. It is based on the bloc pattern, discussed in detail in the Flutter documentation.

We are still going strong with this, and it was a very good decision to make the transfer.

Today, our app is still in active development (obviously, as it has only been two months), and we feel that it is build on solid ground.

TLDR

Our app is based on the bloc pattern (Google it and love it), with the bloc package at its core. It interfaces very well with our firebase backend, and we have established some awesome development patterns.

Advice to Flutter newcomers

  • Learn the Dart language (classes, constructors, functions and get very well acquainted with maps in Dart. Working with these is not quite the same experience as in JS... ).

  • Learn Flutter (duh). Getting a grasp of how UI is built and structured should be very familiar to a React developer. Familiarize yourself with building UI with objects rather than JSX and you are good to go.

  • Make a choice in regards to state management. The Flutter documentation offers a lot of information on this topic, and it is very easy to find examples. My personal bias goes towards the bloc package. It has a bit of a learning curve, but reading through the documentation will give you a sound understanding of how you get the most out of Flutter.

Enjoy - and good luck!

Discussion

pic
Editor guide