Skip to content

Instantly share code, notes, and snippets.

@venkatd
Last active July 14, 2020 12:51
Show Gist options
  • Save venkatd/e75fb302ed43a1f4420e225fb017e69e to your computer and use it in GitHub Desktop.
Save venkatd/e75fb302ed43a1f4420e225fb017e69e to your computer and use it in GitHub Desktop.

Composition challenges

  • State management
    • pending messages
    • file upload progress
    • replacing the initState logic in ChatScreen
  • Reusing screens
    • Time entry edit vs. create time entry
    • popping screen returns value?
final authService = Provider((ref) {
    final config = ref.read(appConfigProvider);
    return AuthService(authUrl: config.authUrl);
});

final apiProvider = Computed((ref) {
    final userId = ref.read(authStateProvider(ref)).user.id;
    // final userId = authStateProvider(ref).user.id
    final client = ref.read(graphQLClientProvider(userId));
    // final client = graphQLClientProvider(ref, userId)

    final api = TurtleAPI(graphQLClient: client)

    ref.onDispose(() { // if null, does nothing
        api.dispose();
    });

    return api;
})

final currentUserProvider = Computed((ref) {
    return ref.read(authServiceProvider).user;
});

final paginatedMessageList = ComputedChangeNotifier<String>((ref, chatId) {
    final api = ref.read(apiProvider);
    // final api = apiProvider(ref);

    final messageList = PaginatedMessageList(api, chatId: chatId);

    ref.onDispose(() { // if null, does nothing
        messageList.dispose();
    });

    return messageList;
})

Provider

Recomended uses

  1. app-specific state management
  • Todo lists
  • Data for the logged in user
  1. app-specific dependencies
  • AuthService
  • Repository of todos
  • GraphQL/HTTP client

Properties

  • A provider is a 'selector' function that is cached on first access. It can depend on the value of other selectors. ref.get(myProvider) will return the same value if called twice.
  • A provider will not recompute if its dependencies change

Hooks

Recommended uses

  • Replaces lifecycle hooks and setState
  • General purpose widget-specific state management
    • useTextEditingController()
    • useConnectionState()
    • useChangeListener(itemToListenTo)
    • useProvider(myProvider)

Properties

  • Can only be called in the build method
  • Forces a rebuild at certain points and may have different return values (specific to the implementation of each hook)
    • useFuture(future) -> right away, after resolved/error (AsyncValue)
    • useStream(stream) -> every time a new value is emitted
  • When the build method is called, each x = useX() call will have the most recent value available
  • Some hooks have destructor methods that get called automatically when they are no longer used

Example

Widget build(BuildContext context) {
   // every time connectionState changes, build is called with latest values of connectionState, query
   final connectionState = useConnectionState(); // State.Connected | State.Connecting | State.Disconnected
   // every time query status changes, `build` is called with latest values of connectionState, query
   final query = useQuery(graphql, vars); // AsyncValue<QueryResult> (loading | error | data)
   
   ... build logic ... 
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment