Redux, the ideal Flutter pattern?

When starting with Flutter I was looking for recommendations for App architecture and most of the time I found references to the Redux pattern.
I'm really honest, Redux never appealed to me. I understand the idea behind the unidirectional data flow but it just seemed too much overhead.

But I wanted to take it to a test and try to create App that is identical to one created with Redux but with the RxVAMS pattern (which I proposed in my last blog post) .

When Iiro Krankka open sourced his beautiful App inKino which is build using redux I had my candidate.

inKino

I asked Iiro if it would be ok if I take his App and refactor it to RxVAMS and he is looking forward to the outcome.

Trying to find out how an Redux app works turned out to be more difficult than expected. Normally when inspecting source code of an app someone else wrote I start with the UI trying to follow the program flow that is triggered by an user action. Trying to do that by using the IDE's "Go to definition" and "Find all references" didn't really help because of the way Redux decouples classes. I can only agree with Paul Betts on this:

paulbettsonredux

Comparing the project structure

folder-structure-reduxfolder-structure-rx

The Redux version needs 24 classes for its state management where the Rx version only uses one: app_model.dart


Raw numbers

I wrote a small analysis tool DartStatistics to count code lines, characters and number of classes:

Version Code Lines Code characters classes
Redux 3109 74561 75
RxVAMS 2412 56137 44

This means Redux needs about 30% more lines and characters of code than RxVAMS to achieve the same functionality.

But what if the App gets more complex?

As this App only has one real Page with user interaction I use only one class the AppModel to hold all state of the App. If the App would consists of more complex pages the AppModel would provide a PageModel for each of this Pages that would relay data to the AppModel or directly to the service layer.

The Redux version stores all app state inside one store class so not so much difference here but it needs a lot more code to access and modify it.

But, but Redux will prevent a lot of errors!

True, the fact that views cannot modify state directly but only over dispatching actions might beware you of potential errors but for the price that your code gets much harder to understand and you have to create much more code to reach that goal.
More code also means more places to make mistakes.

Using Streams and RxCommands to communicate between model and view you get an easier to understandable architecture that works without side effects too and you always can follow your code using your IDE's search commands.

Readability before everything else

If you ever came back to one of your own project after a year you know the feeling to have the feeling someone else must have written this code. Same for any developer that gets the task of continuing the development of a project because the original creator has left the company. So easy to understand and to follow code is paramount.

Why do we use complex patterns?

  • Reusability of code: I really would like to know how many of you have really reused bigger parts of an App in completely different one that wouldn't be better placed in a independent library from the begin.
  • Exchangeability of components: Often be introduce additional abstraction layers. But who of you have really changed the database after an app was finished?
  • Extensibility: I think it was Kent Beck the creator of Extreme Programming how made the point that using modern IDEs it's pretty easy to make big refactorings even in large code bases. Having automated tests implemented make sure that you don't accidentally break something.
  • Error prevention: State management is one of the most difficult areas of any App so using patterns that preventing side effects are a good idea. If one pattern will save you at the end of the day will only show time. Choose a pattern that doesn't compromise understandability of your code.
  • Testability: This is actual the one that has shown its benefits in daily use. But even here I always will prefer manual Dependency injection before automagically working IOC containers.

I don't say that these goals are not important and may be helpful from time to time but I want to encourage you to question existing development trends and hypes. Trying to strive for simplicity is a good goal overall.

Try it on your own

O.K. you got it, I don't like Redux 🙂 You don't have to believe me so give it a try yourself. Clone both repositories and try to understand how the apps work and share your experiences with us in the comments. I'm really curious to hear them.

Here are the repositories:

Redux inKino

RxVAMS inKinoRx

I'm still exploring how to refine the use of RxCommands with Flutter and there are still some points where I'm not completely satisfied but I will continue this exploration and hope some of you will join me.

Contact me:

13 thoughts on “Redux, the ideal Flutter pattern?

  1. GĂŒnter Zöchbauer says:

    Why do we use complex patterns?

    I think the most important point is missing here.

    Patterns are well understood and well documented.

    This makes them easier to learn and replicate and also requires less documentation in code and makes communication easier because there provide established terminology.

    • admin says:

      That’s an important point I agree but does not require unnecessary complex patterns

  2. Martin Nowosad says:

    You should state that Redux IS the architecture of the Project. Which is a big no go, since the decision to choose frameworks and databases and other details should be one of the last ones. A clean architecture should be completely decoupled from any 3rd party frameworks. By picking Redux you’re not only choosing the framework at a very early stage, you’re coupling your architecture to it. Your App is basing on Redux. A more experienced developer should be thinking twice before giving the potential of his software architecture away to redux.

    • admin says:

      Not sure that you read the post carefully enough. My version of the App doesn’t use redux.
      Also redux isn’t only a framework but also an architectural pattern.

    • GĂŒnter Zöchbauer says:

      Redux is more a pattern than a framework.
      Using packages to avoid some boilerplate doesn’t count as “framework” to me.
      Where would that end? Not using standard libaries?

      • Swav Kulinski says:

        Agree, simple implementation doesn’t require any library at all. Just follow the principles of the pattern. Library is to provide decoupling when your app gets bigger.

        My favourite part of redux is this rule set which doesn’t constrain implementation but enforces the right way of thinking.

        Flutter and ReactNative stand on the ground of giving away power that engineers have (to do right or wrong things) and give it to UX designers (we usually don’t want to listen to)

  3. Oskar says:

    Hi, great post! I have a question – what is the best way to manage advanced project with few modules? Here is my case:
    App starts, then checks if user is logged in. If true go to Dashboard, else go to login page.
    Logged user can open drawer and see all modules (Tasks, Chat, Contacts, Settings, etc.). How should I set current page in that pattern? By changing body part in Main Page?
    I will by grateful for your help.

    • admin says:

      Hi Oskar,

      I would make a StartUpPage the BasePage of your App and push a LoginPage on top for login and replace that with your Dashboard page after successful login.

  4. Hi – I’ve been reading your blogs and watching your videos about RxVMS and I desire to understand how it works. I also want to understand this Redux/Rx comparison. I pulled down each version and discovered major discrepancies in quality. Without a one-one feature parity, (and I assume I’m not missing something / somewhere e.g. the app is currently broken?) the statistics comparing inKino/Redux w/ inKino/Rx are not accurate or fair. I don’t understand enough at this time to help debug RxVMS.

    Here’s a list of items I found that need attention:

    0) The front page is not even the same
    Redux has bottom app bar with Icons, no Drawer, but Location icon for picking Theater
    Rx doesn’t – not sure it matters but i’m trying to compare apples to apples
    1) I see the same movies for both Redux / Rx
    2) I pick a Theater and the list updates the same for both Redux / Rx
    3) I click the “Showtimes” tab.
    Rx version shows blank page. Nothing. No Calendar on top. No showings.
    Redux version shows Calendar on top and when I pick date, I get showings.
    4) From main list, I click “Ailo” movie
    Rx version does not show the Gallery pictures
    Redux shows 2 gallery pictures
    5) From main page, I click Search icon
    Rx Nothing happens as I enter ‘A’ then ‘i’ – nothing
    Redux filters the list as each letter is entered
    6) Clicking the “Coming soon”
    Rx does not show the “Release date”
    Redux shows “Release date” in top left corner
    7) From “Coming Soon”, scroll to bottom and see Gallery
    Rx does not show Gallery (maybe redundant w/ 4)
    Redux does
    8) From Detail page, I pull down, the Image changes / enlarges
    Rx does not change on pull down – no pull down action at all
    Redux does change the image with pull down
    9) Tests
    Rx tests have many errors
    Redux all tests compile and run successfully
    10) Performance running both on iOS Simulator
    Scrolling on both seems on par

    Regards, thanks for taking on this Redux/RxVMS project – it’s a good reference project.

    • Thomas Burkhart says:

      I’m sorry if that is the case. I guess the original inKino has evolved since when I wrote the Article.

  5. JohnDoe says:

    Hi, good post 🙂
    I think that implementing redux is a nightmare compared to bloc..
    However, these two don’t seem to be an alternative to one another, but actually complement each other.
    For local state management it might stand to reason to use bloc. But for global state.. it is just like ViewModel in Android – it’s attached per screen(activity). You cannot (unfortunately) rely on it for global state management.
    For example, ‘session’ kind of stuff, like the language/locale of the user, etc. You would rather access it in one place, from all the pages you have, instead of having duplicate “view models” that pass these values from one to another.
    Correct me if I wrong though, as I would love to be able to not have to deal with Redux 😉

Leave a Reply to admin Cancel reply

Your email address will not be published. Required fields are marked *