marcglasberg / async_redux

Flutter Package: A Redux version tailored for Flutter, which is easy to learn, to use, to test, and has no boilerplate. Allows for both sync and async reducers.
Other
234 stars 40 forks source link

Is it ok for a #39

Closed RudolfVonKrugstein closed 4 years ago

RudolfVonKrugstein commented 4 years ago

Let's assume I have an AppState like this:

class ListItem {
    final String stuff;
    final int moreStuff;
}

class AppState {
    final List<ListItem> items;
}

Now I want to write a widget, that displays a single ListItem:

class _ViewModel {
    _ViewModel fromStore(...) { 
        // How do I get the ListItem to derive data from?
    }
}

class ListItemWidget extends StatelessWidget {
    ListItemWidget(ListItem listItem);
    final ListItem listItem;
    @override
    Widget build(BuildContext context) {
        return StoreConnector<AppState>(
            mode: _ViewModel
            child: ListTile(/*Stuff based on an instance of ListItem */);
        );
    }
}

Now the problem is: The _ViewModel must be created with a particular ListItem, and just passing the store to it (in fromStore) is not enough because I would not know which ListItem to use. I could write a converter and a second factory function to create the _ViewModel. In that case, I could pass the ListItem to the converter and the factory function. But it seems kind of hacky to me, because I am ignoring the fromStore constructor.

How would you do this?

marcglasberg commented 4 years ago

I'm not sure your question makes sense. If your ListItemWidget accepts a ListItem in its constructor, then you don't need any info from the store anymore. Just do this:

class ListItemWidget extends StatelessWidget {
    ListItemWidget(ListItem listItem);
    final ListItem listItem; 
   @override
    Widget build(BuildContext context) =>ListTile(listItem); 
}

If you are trying to display list items from their indexes, then you could read them from the store, like this:

class ListTileConnector extends StatelessWidget {
    ListItemWidget(int index);
    final int index;
    @override
    Widget build(BuildContext context) {
        return StoreConnector<AppState>(
            converter: ViewModel.from(store, index),
            child: ListTile(vm.listItem);
        );
    }
}

class ViewModel {
   ListItem listItem;

   ViewMode(this.listItem);

    ViewModel from(Store store, int index) { 
        return  ViewModel(store.items[index]) 
    }

   // Don't forget to add equals/hashcode here.
}

Or maybe you just want to read the whole list from the store at once, like this:

class ListOfAllItemsConnector extends StatelessWidget {
    @override
    Widget build(BuildContext context) {
        return StoreConnector<AppState>(
            converter: ViewModel.from(store),
            child: ListOfAllItems(vm.list);
        );
    }
}

class ViewModel {
   List<ListItem> list;

   ViewMode(this.list);

    ViewModel from(Store store) { 
        return  ViewModel(store.items) 
    }

   // Don't forget to add equals/hashcode here.
}