Skip to content

Instantly share code, notes, and snippets.

@rrousselGit
Last active October 12, 2021 15:12
Show Gist options
  • Save rrousselGit/06842ae9e4b82fad917acb88da108eee to your computer and use it in GitHub Desktop.
Save rrousselGit/06842ae9e4b82fad917acb88da108eee to your computer and use it in GitHub Desktop.
import 'package:flutter/material.dart';
// This example showcases how by using functions instead of StatelessWidgets,
// this can cause bugs when using InheritedWidgets
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(context) {
print('this build method is called only once');
return Counter(
count: Count(),
child: MaterialApp(
home: Home(),
// Uncomment to make your app crash
// And if you fix the error, rebuilding the counter will rebuild MyApp
// home: home(context),
),
);
}
}
class Count extends ValueNotifier<int> {
Count() : super(0);
}
class Counter extends InheritedNotifier {
Counter({
Key key,
this.count,
Widget child,
}) : super(key: key, child: child, notifier: count);
final Count count;
static Count of(BuildContext context) {
return context.dependOnInheritedWidgetOfExactType<Counter>().count;
}
}
class Home extends StatelessWidget {
@override
Widget build(BuildContext context) {
print('Home is re-executed without re-executing MyApp');
return Scaffold(
body: Center(
child: Text('Count ${Counter.of(context).value}'),
),
floatingActionButton: FloatingActionButton(
onPressed: () => Counter.of(context).value++,
child: Icon(Icons.add),
),
);
}
}
Widget home(BuildContext context) {
// Throws by default
// To fix, either use a Builder (which wouldn't solve the AnimatedSwitcher issue in https://dartpad.dev/1870e726d7e04699bc8f9d78ba71da35)
// Alternatively, you could move Counter() above MyApp, but then MyApp would
// rebuild whenever the counter changes
return Scaffold(
body: Center(
child: Text('Count ${Counter.of(context).value}'),
),
floatingActionButton: FloatingActionButton(
onPressed: () => Counter.of(context).value++,
child: Icon(Icons.add),
),
);
}
@craiglabenz
Copy link

Thanks for these gists - here's one last update to make the analyzer happy :)

import 'package:flutter/material.dart';

// This example showcases how by using functions instead of StatelessWidgets,
// this can cause bugs when using InheritedWidgets

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(context) {
    print('this build method is called only once');
    return Counter(
      count: Count(),
      child: MaterialApp(
        // home: Home(),
        // Uncomment to make your app crash
        // And if you fix the error, rebuilding the counter will rebuild MyApp
        home: home(context),
      ),
    );
  }
}

class Count extends ValueNotifier<int> {
  Count() : super(0);
}

class Counter extends InheritedNotifier {
  const Counter({
    Key? key,
    required this.count,
    required Widget child,
  }) : super(key: key, child: child, notifier: count);

  final Count count;

  static Count of(BuildContext context) {
    return context.dependOnInheritedWidgetOfExactType<Counter>()!.count;
  }
}

class Home extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    print('Home is re-executed without re-executing MyApp');
    return Scaffold(
      body: Center(
        child: Text('Count ${Counter.of(context).value}'),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () => Counter.of(context).value++,
        child: const Icon(Icons.add),
      ),
    );
  }
}

Widget home(BuildContext context) {
  // Throws by default
  // To fix, either use a Builder (which wouldn't solve the AnimatedSwitcher issue in https://dartpad.dev/1870e726d7e04699bc8f9d78ba71da35)
  // Alternatively, you could move Counter() above MyApp, but then MyApp would
  // rebuild whenever the counter changes
  return Scaffold(
    body: Center(
      child: Text('Count ${Counter.of(context).value}'),
    ),
    floatingActionButton: FloatingActionButton(
      onPressed: () => Counter.of(context).value++,
      child: const Icon(Icons.add),
    ),
  );
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment