This is the last of a three-part series. In part one, we defined where React Native and Flutter fit in with all cross-platform solutions and why we’d want to focus on these two heavyweights. In part two, we compared their histories, design, and performance. And in part three (this part), we’ll look at the same component built in both React Native and in Flutter.
The theory and the ideas are very important but many developers need to actually see some code before their minds are made up. After all, if the experience of development is miserable, your apps will be neither fast nor pretty because talented developers will choose to work with another framework — with you or with your competition. In order for you to get a complete picture we’ve developed an app that does exactly the same thing on both frameworks.
This demonstration app could be used by a movie theater to allow their users to reserve tickets for a show. They’ll choose a date and a movie to watch. They’ll choose a showtime and pick the seats they’ll sit in. The screenshot of the left is from the React Native version and the one on the right was created using Flutter. As you can see they are nearly identical.
This demo app involves the major capabilities you’d want to see exercised; custom components/widgets, stateless and stateful components/widgets, platform-specific coding, reading and writing to a database via a RESTful API, asynchronous coding and more. The entire codebase is available to you at https://github.com/rapPayne/react-native-vs-flutter. We’ve included some samples below and annotated them with notes. We’ll use these to compare as we dig deeper into the similarities and differences. Let’s start with the structure of a component.
Remember that everything you write is a component in React Native or a widget in Flutter. Looking at this fundamental building block exposes major differences between the frameworks.
A stateful component in React Native
A stateful widget in Flutter
1. The framework itself must be imported. React Native requires you to import each native component individually while Flutter imports them all as a group.
3. Importing other custom components/widgets.
4. Creating a stateful class in React Native is much simpler than the equivalent in Flutter. Flutter explicitly splits its component into a state class and a component class. This is harder to write and learn but gives us more control.
5. The class’s constructor is called only on creation of the component.
6. Working with Redux. React Native allows more explicit control of state than Flutter. Both require you to call this.setState() in order to mutate state. This cannot be a coincidence. Google clearly learned some lessons from React Native’s successes. This is just another example of those lessons.
7. React Native has lifecycle methods that allow tight control over when things happen. Flutter has lifecycle methods also but because Flutter has separated a State class from the component class, Flutter needs fewer.
8. Where the visual component sub-tree is created. It must be a method called render() in React Native and must be called build() in Flutter. We’ll look at those methods in the next section.
Both frameworks have a required method of the class where the tree of sub-components are rendered. It is called render() in React Native and build() in Flutter. Here is the render() method of the Landing component made with React Native.
Building the UI in React Native
Building the UI in Flutter
10. A component/widget that allows full-screen viewing even on devices with a notch, like on the iPhone X. This is needed to wrap the Landing widget on Flutter so it is actually one level higher. It is called a SafeArea widget.
11. Allows the user to scroll contents by swiping their finger up and down. To overflow the screen in React Native creates an inaccessible area. This is bad. To overflow it it in Flutter is a runtime error. This is worse.
12. To layout components above and below in React Native, you wrap them in a plain <View> component. To lay them out side-by-side, you also use a <View> component, but you style it using flexbox like in HTML. In Flutter, above-and-below is done with Column widgets and side-by-side is done with Row widgets. This is more intuitive.
13. An image whose source is bundled with the application and deployed as part of the installation on each user’s device.
14. React Native makes it possible to set styles separately from components. Flutter requires that styling information resides in the individual widgets. This means styling at a lower level in Flutter but may make it easier to debug styling issues since the styling information will always be found in the same place.
15. A simple text component/widget.
16. The DatePicker is a custom component/widget. Because React Native uses the underlying platform-specific implementation for picking dates, it required us to use device detection (ie. “if iOS, do one thing. If Android, do another”). Flutter has the ability to match native look but never forces you to do that. So Flutter was much simpler.
18. This is iterating; looping through a collection of objects and rendering one custom component/widget per member. Here, we are iterating the films and rendering one FilmBrief component/widget to draw the film’s poster, title, and tagline. Like before, neither framework allows the expected for loop but instead uses the .map() method.
19. Creating a modal window. Note that the structure is defined inside of it. This could be done inline or via a function call.
So which is better?
Developers have opinions (duh). If you’re deciding between the two frameworks, you might want to run these snippets by your team and encourage a discussion as to which they feel would be more effective.