Before you learn how to use AppRoute, take a look at these questions and decide if this is what you need

  1. Why are redux.js and Vuex global stores?

    Single-page applications on the front end are increasingly complex, with one model change leading to another model change, which may lead to view changes. Redux’s three principles make predictable changes in state possible. The first of these is a single data source, which embodies the idea of centralization. Applications maintain a state tree, and data changes drive views to refresh. A single state tree makes it easier to manage data and share data (such as login information) between components due to the same lifecycle as the App.

  2. Why isn’t Fish Redux like this?

    At the beginning, Fish Redux only supported page-level Stroe, which was the objective appeal of the business. Flutter is a new stack of technologies that need to be used in an App with hundreds of millions of users. It requires risk control and isolation, and can only be replaced by rewritten pages, validated iterations, and phased replacements.

  3. Do I need to use AppRoute?

    If your appeal is the same as that of idle fish, you are taking the difficult route, which requires a long struggle between concentration and division. HybridRoute is suggested to save some time and facilitate the subsequent transformation. Otherwise, use AppRoute and enjoy the advantages of Flutter and Redux.

Design idea

The author adds the Route layer, whose core function is to generate a Page corresponding to different scenarios, and realizes three specific XXxroutes

/// Route abstract class, which only provides the ability to return a page
abstract class AbstractRoutes {
  Widget buildPage(String path, dynamic arguments);
}

/// AppRoutes implements multiple page common store, suitable for new App use
class AppRoutes<T> implements AbstractRoutes {
  final Map<String, Dependent<T>> pages;
  finalPageStore<T> _store; . }/// One page, one store, suitable for partial page adaptation of FLUTTER App, such as the current Xianyu
class PageRoutes implements AbstractRoutes {
  final Map<String, Page<Object.dynamic>> pages; . }/// Mix Routes, you can use both AppRoutes and PageRoutes at the same time, suitable for both apps, such as Xiayu in the future
class HybridRoutes implements AbstractRoutes {
  final List<AbstractRoutes> routes; . }Copy the code

use

  1. Define an AppRoute

    /// app_route.dart
    /// use the singleton to call the global singleton
    class AppRoute {
      static AbstractRoutes _global;
      static AbstractRoutes get global {
        if (_global == null) {
          _global = AppRoutes(preloadedState: AppState.initialState(), pages: {
            // There are two ways to write it, and the effect is the same.
            // RoutePath.todoList: TodoListPage().asDependent(TodoListConn()),
            RoutePath.todoList: TodoListConn() + TodoListPage(),
            RoutePath.todoDetail: TodoDetailConn() + TodoDetailPage(),
          });
        }
        return_global; }}/// reduce the magic field, these constants can also be placed in constant, just for convenience.
    class RoutePath {
      static const String todoList = 'todo_list';
      static const String todoDetail = 'todo_detail';
    }
    Copy the code
  2. Define an AppState to be used as the root node of the state tree

    /// screens/todo_list/state.dart
    class AppState implements Cloneable<AppState> {
      TodoListState todoListState;
      TodoDetailState todoDetailState;
    
      AppState(this.todoListState, this.todoDetailState);
    
      @override
      AppState clone() {
        return AppState(todoListState, todoDetailState);
      }
    
      AppState.initialState()
          : todoListState = initState(null),
            todoDetailState = TodoDetailState();
    }
    Copy the code
  3. Define Connect to describe the transformation relationship between subState and parent State

    /// screens/todo_list/state.dart
    /// get takes a small state from a large state and sets a small state
    class TodoListConn extends ConnOp<AppState.TodoListState> {
      @override
      TodoListState get(AppState state) => state.todoListState;
      
      @override
      void set(AppState state, TodoListState subState) =>
          state.todoListState = subState;
    }
    Copy the code
  4. Replace the way the Page was generated

    /// main.dart
    home: AppRoute.global.buildPage(RoutePath.todoList, null),
    Copy the code
  5. Additional processing (Page with data jump)

    /// screens/todo_detail/reducer.dart
    /// page jump may have data passing, such as list to detail page, need to pass id,
    /// When will the data be delivered? [AbstractRoutes] AbstractRoutes
    /// buildPage takes arguments, dynamic you can pass arbitrary structured data, Map is recommended, native JSON style
    // If arguments are not null, Route will send a Route Action.
    Therefore, we need to deal with this in the corresponding Reducer
    Reducer<TodoDetailState> buildReducer() {
      return asReducer<TodoDetailState>(<Object, Reducer<TodoDetailState>>{
        RouteAction.route: _route,
          ...
      });
    }
    
    // get the route Action and update the state id
    TodoDetailState _route(TodoDetailState state, Action action) {
      final TodoDetailState newState = state.clone();
      newState.id = action.payload['id'];
      return newState;
    }
    Copy the code

Compare and experience the Flutter Redux

The best practices of Fish Redux and Flutter Redux have always been different. One is page-level state management and the other is app-level state management, so it is a mismatched competitor. After Fish Redux added Route, it also counted all of them.

  1. Convenient degree

    Flutter Redux is easy to call, but it is more difficult to understand the MEANING of the API. Fish Redux has many concepts, which feels like flat two-dimensional array. A large number of definitions and concepts may discourage some impatient students. However, the intent of the framework is clear, and the code shows signs of careful design. That’s an even point for me.

  2. Document example

    Flutter Redux wins, with much more documentation and examples than Fish Redux, which has only a few documents but is available in Chinese

  3. The problem response

    Fish Redux is the winner, and the Github Issue can basically get a reply and answer from the author or enthusiastic users within 12 hours. The author of Flutter Redux maintains many libraries and has limited energy, so the Issue processing speed can be said to be slow

  4. Complete degrees

    Functionally complete. Formally, Flutter Redux relies on two libraries. Fish Redux does a little better than any other tripartite dependencies

  5. performance

    In fact, the original intention of state management is not to care much about performance, after all, it is just state management, management costs extra. But Fish Redux did take a look at the big list scenario and did a great job optimizing it for performance.

Conclusion: Fish Redux is a viable alternative to Flutter state management, and it is growing as fast as the naked eye can see.

subsequent

After comparison, I think Fish Redux is good and I want to sell it to the chief

I: Report to the boss, Ali’s Fish Redux is old, should we not use it in our project?

Boss: Which NB?

Me: Blah blah blah ~

Boss: Which big factories are using it

Me: Well, it looks like Ali

Boss: How much does the unit test cover?

Me: 50% faster

Boss: How much is the performance improved? Do you have benchmark?

Me:…

Sorry, that’s what I imagined, but with my boss’s expertise, these are the questions I have to ask…

In this paper, the source address: https://github.com/hyjfine/flutter_redux_sample/tree/fish-redux-route

(after)

@ Zi Luyu, the copyright of this article belongs to Zaihui RESEARCH and development team, welcome to reprint, please reserve the source.