alibaba / fish-redux

An assembled flutter application framework.
https://github.com/alibaba/fish-redux
Apache License 2.0
7.33k stars 843 forks source link

Сontinuous page refreshing #629

Open vdvpie22 opened 4 years ago

vdvpie22 commented 4 years ago

I have the page with component on it. When I change local state of component, page will reloaded. Can I change local state of component without page reloading?

Component:

class MessagesComponent extends Component<MessagesState> {
  MessagesComponent()
      : super(
            effect: buildEffect(),
            reducer: buildReducer(),
            view: buildView,
            dependencies: Dependencies<MessagesState>(
                adapter: null,
                slots: <String, Dependent<MessagesState>>{
                }),);

}

Component state:

class MessagesState implements Cloneable<MessagesState> {
  int messageCount;

  @override
  MessagesState clone() {
    return MessagesState()..messageCount = messageCount;
  }
}

MessagesState initState(Map<String, dynamic> args) {
  return MessagesState();
}

Component Actions:

class MessagesActionCreator {
  static Action setMessageCount(int count) {
    return Action(MessagesAction.setMessageCount, payload: count);
  }

  static Action onSetMessageCount(int count) {
    return Action(MessagesAction.onSetMessageCount, payload: count);
  }
}

Component Effect:

Effect<MessagesState> buildEffect() {
  return combineEffects(<Object, Effect<MessagesState>>{
    MessagesAction.onSetMessageCount: _onSetMessageCount,
  });
}

void _onSetMessageCount(Action action, Context<MessagesState> ctx) {
  Scaffold.of(ctx.context)
    ..removeCurrentSnackBar()
    ..showSnackBar(SnackBar(
      content: Text("Сообщения"),
    ));
  ctx.dispatch(MessagesActionCreator.setMessageCount(action.payload));
}

Component Reduser:

Reducer<MessagesState> buildReducer() {
  return asReducer(
    <Object, Reducer<MessagesState>>{
      MessagesAction.setMessageCount: _setMessageCount,
    },
  );
}

MessagesState _setMessageCount(MessagesState state, Action action) {
  final MessagesState newState = state.clone();
  newState.messageCount = newState.messageCount + action.payload as int;
  return newState;
}

Component View:

Widget buildView(
    MessagesState state, Dispatch dispatch, ViewService viewService) {
  int messageCount = state?.messageCount;

  return Container(
    child: Padding(
      padding: EdgeInsets.all(15),
      child: RaisedButton(
        onPressed: () {
          dispatch(MessagesActionCreator.onSetMessageCount(1));
        },
        color: Colors.blue,
        child: Stack(
          children: <Widget>[
            Container(
              alignment: Alignment(-1.0, 0.0),
              child: Icon(
                Icons.notification_important,
                color: Colors.white,
              ),
            ),
            Container(
              padding: EdgeInsets.only(top: 3),
              alignment: Alignment(0.0, 0.0),
              child: Text($messageCount',
                style: TextStyle(color: Colors.white),
              ),
            ),
          ],
        ),
      ),
    ),
  );
}

Connector:

class MessagesButtonConnector extends ConnOp<HomeState, MessagesState> {
  @override
  MessagesState get(HomeState state) => state.messagesState;

  @override
  void set(HomeState state, MessagesState subState) =>
      state.messagesState = subState;
}

Page:

class HomePage extends Page<HomeState, Map<String, dynamic>> {
  HomePage()
      : super(
          initState: initState,
          effect: buildEffect(),
          reducer: buildReducer(),
          view: buildView,
          dependencies: Dependencies<HomeState>(
              adapter: null,
              slots: <String, Dependent<HomeState>>{
                'messages_button':
                    MessagesButtonConnector() + MessagesComponent()
              }),
          middleware: <Middleware<HomeState>>[],
        );
}

Page State:

class HomeState implements GlobalBaseState<HomeState> {
  String address;
  BottomNavigationBarState bottomNavigationBarState;
  MessagesState messagesState;

  @override
  int pageIndex;

  @override
  String user;

  @override
  HomeState clone() {
    return HomeState()
      ..user = user
      ..address = address
      ..pageIndex = pageIndex
      ..bottomNavigationBarState = bottomNavigationBarState
      ..messagesState = messagesState;
  }
}

HomeState initState(Map<String, dynamic> args) {
  return HomeState()
    ..bottomNavigationBarState = BottomNavigationBarState()
    ..messagesState = MessagesState()
    ..messagesState.messageCount = 0;
}
dddrop commented 4 years ago
class HomePage extends Page<HomeState, Map<String, dynamic>> {
  HomePage()
      : super(
          initState: initState,
          effect: buildEffect(),
          reducer: buildReducer(),
          view: buildView,
          dependencies: Dependencies<HomeState>(
              adapter: null,
              slots: <String, Dependent<HomeState>>{
                'messages_button':
                    MessagesButtonConnector() + MessagesComponent()
              }),
          middleware: <Middleware<HomeState>>[],
          // 
          shouldUpdate: (HomeState oldState, HomeState newState) {
             // Add your own rules to define when will rebuild the view.
             return true;
          }
        );
}