Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ScrollController is not working with Redux #72

Closed
baoxiehao opened this issue Aug 15, 2018 · 6 comments
Closed

ScrollController is not working with Redux #72

baoxiehao opened this issue Aug 15, 2018 · 6 comments

Comments

@baoxiehao
Copy link

baoxiehao commented Aug 15, 2018

Hi, I'm new to flutter and I'm building a learning app which needs to listen to scroll view and do loading more function. And also, flutter_redux is included in my project cause it's awesome for decoupling data and view. But now I come across the problem that the listener added to ScrollController used by GridView is not working. Following is the code, pls help me out if I'm using it wrong. Hope someone could help me, thanks.

class HomePage extends StatelessWidget {

  HomePage({
    Key key,
    this.category
  })
    : super(key: key);

  final GankCategory category;

  ScrollController _scrollController = ScrollController();

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: StoreBuilder<AppState>(
        onInit: ((store) {
          print('onInit');
          _scrollController.addListener(() {
            print('${_scrollController.position}'); // NO PRINT LOGS using flutter logs WHEN I AM SCROLLING
            if (_scrollController.position.pixels == _scrollController.position.maxScrollExtent) {
              print('loadMore');
              dispatchAction(store, UpdateCurrentPageAction(currentPageSelector(store.state) + 1));
              dispatchAction(store, LoadGanksAction());
            }
          });
        }),
        onDispose: ((store) {
          _scrollController.dispose();
        }),
        builder: (context, store) {
          return RefreshIndicator(
            onRefresh: (() {
              dispatchAction(store, UpdateCurrentPageAction(0));
              dispatchAction(store, RefreshGanksAction());
              return null;
            }),
            child: GridView.count(
              crossAxisCount: 2,
              controller: _scrollController, // HERE I USE the controller
              physics: BouncingScrollPhysics(),
              padding: EdgeInsets.all(16.0),
              childAspectRatio: 16.0 / 17.0,
              children: ganksSelector(store.state).map((gank) {
                return _buildHomeCard(context, gank);
              }).toList(),
            ),
          );
        },
      ),
    );
  }
  ...
}
@baoxiehao
Copy link
Author

Found out why. The controller should be working with StatefulWidget only like animations.
So if someone using flutter redux within StatelessWidget, pls surround the presentation part by StatefulWidget to do the scroller or animation work.

class HomePage extends StatelessWidget {

  HomePage({
    Key key,
    this.category
  })
    : super(key: key);

  final GankCategory category;

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: StoreBuilder<AppState>(
        builder: (context, store) {
          return _HomeGridViewWidget(
            ganks: ganksSelector(store.state),
            currentPage: currentPageSelector(store.state),
          );
        },
      ),
    );
  }
}

class _HomeGridViewWidget extends StatefulWidget {

  final List<Gank> ganks;
  final int currentPage;

  const _HomeGridViewWidget({Key key, this.ganks, this.currentPage}) : super(key: key);

  @override
  State<StatefulWidget> createState() => _HomeGridViewState();
}

class _HomeGridViewState extends State<_HomeGridViewWidget> {
  ScrollController _scrollController = ScrollController();
  ...
}

@baoxiehao
Copy link
Author

baoxiehao commented Aug 15, 2018

@brianegan One more question, like the code snippet above, I just use the StoreBuilder and subselect the needed sub app state down to the stateful _HomeGridViewWidget. Should I use a converter here like StoreConnector? If not, are there any difference with StoreBuilder and StoreConnector? I guess StoreBuilder will rebuild itself when any sub app states change and StoreConnector will rebuild itself only when the converted sub app states change?

@brianegan
Copy link
Owner

brianegan commented Aug 15, 2018

Yep! In the first example, you'll be creating the controller over and over, which might cause some problems.

I tend to like StoreConnector's because it allows you to separate "Smart Widgets" from "Dumb Widgets." The Smart Widgets connect to the Store and prepare the data for the "Dumb Widgets." You can then re-use the Dumb widgets in more places without them needing to know anything about the Store / data source.

In addition, you can use the StoreConnector to optimize rendering as you suggest. If you use a StoreConverter, set distinct: true in the constructor, and implement == on the value that's returned from the StoreConnector, it will only trigger the builder function when the Data you're extracting from the store has indeed changed.

@baoxiehao
Copy link
Author

@brianegan Thanks you for your reply.
Actually I learn the flutter redux example of the Todo app, it is a very good start for the redux pattern.
so the distinct: true is only working with StoreConnector, which is not available for StoreBuilder right?

@brianegan
Copy link
Owner

brianegan commented Aug 15, 2018

Yep! StoreBuilder will always pass the same object to the builder function (the store). Therefore, if distinct: true was set, it'd never trigger a rebuild since the store will always be the same.

I'll go ahead and close this out for now, but please feel free to file another issue if ya need more help :)

@baoxiehao
Copy link
Author

@brianegan I've got it. Thank you for your help. I think I need to make a live template of Android Studio for the _ViewModel, or it will be tedious to write the _ViewModel class by hand every time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants