ããã¯ïŒ25280ã«é¢ããè°è«ã«é¢é£
TL; DRïŒ State
ããžãã¯ãåå©çšããããšã¯å°é£ã§ãã æçµçã«è€éã§æ·±ããã¹ããããbuild
ã¡ãœããã«ãªãããè€æ°ã®ãŠã£ãžã§ããéã§ããžãã¯ãã³ããŒããŠè²Œãä»ããå¿
èŠããããŸãã
ããã¯ã¹ã€ã³ãé¢æ°ãä»ããŠãã®ãããªããžãã¯ãåå©çšããããšã¯ã§ããŸããã
State
ããžãã¯ãè€æ°ã®StatefulWidget
ãŸããã£ãŠåå©çšããããšã¯ããã®ããžãã¯ãè€æ°ã®ã©ã€ããµã€ã¯ã«ã«äŸåããããã«ãªããšããã«éåžžã«å°é£ã«ãªããŸãã
å
žåçãªäŸã¯ã TextEditingController
ïŒãã ãã AnimationController
ãæé»ã®ã¢ãã¡ãŒã·ã§ã³ãªã©ïŒãäœæããããžãã¯ã§ãã ãã®ããžãã¯ã¯è€æ°ã®ã¹ãããã§æ§æãããŠããŸãã
State
å€æ°ãå®çŸ©ããŸããdart
TextEditingController controller;
dart
<strong i="25">@override</strong>
void initState() {
super.initState();
controller = TextEditingController(text: 'Hello world');
}
State
ãç Žæ£ããããšãã«ãã³ã³ãããŒã©ãŒãç Žæ£ããŸãããdart
<strong i="30">@override</strong>
void dispose() {
controller.dispose();
super.dispose();
}
build
å
ã®ãã®å€æ°ã§ããããããšãäœã§ãããŸããdebugFillProperties
å
¬éããŸãïŒdart
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty('controller', controller));
}
ããèªäœã¯è€éã§ã¯ãããŸããã åé¡ã¯ããã®ã¢ãããŒããæ¡åŒµããããšãã«å§ãŸããŸãã
äžè¬çãªFlutterã¢ããªã«ã¯æ°åã®ããã¹ããã£ãŒã«ããããå ŽåããããŸããããã¯ããã®ããžãã¯ãè€æ°åè€è£œãããããšãæå³ããŸãã
ãã®ããžãã¯ãã©ãã«ã§ãã³ããŒããŠè²Œãä»ãããšãæ©èœãããŸãããã³ãŒãã«åŒ±ç¹ãçããŸãã
dispose
ãåŒã³åºãã®ãå¿ãããªã©ïŒãã®ããžãã¯ãå æ°å解ããæåã®è©Šã¿ã¯ãããã¯ã¹ã€ã³ã䜿çšããããšã§ãã
mixin TextEditingControllerMixin<T extends StatefulWidget> on State<T> {
TextEditingController get textEditingController => _textEditingController;
TextEditingController _textEditingController;
<strong i="11">@override</strong>
void initState() {
super.initState();
_textEditingController = TextEditingController();
}
<strong i="12">@override</strong>
void dispose() {
_textEditingController.dispose();
super.dispose();
}
<strong i="13">@override</strong>
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(DiagnosticsProperty('textEditingController', textEditingController));
}
}
次ã«ã次ã®ããã«äœ¿çšããŸãã
class Example extends StatefulWidget {
<strong i="17">@override</strong>
_ExampleState createState() => _ExampleState();
}
class _ExampleState extends State<Example>
with TextEditingControllerMixin<Example> {
<strong i="18">@override</strong>
Widget build(BuildContext context) {
return TextField(
controller: textEditingController,
);
}
}
ããããããã«ã¯ããŸããŸãªæ¬ é¥ããããŸãã
ããã¯ã¹ã€ã³ã¯ã¯ã©ã¹ããšã«1åã ã䜿çšã§ããŸãã StatefulWidget
ã«è€æ°ã®TextEditingController
ãå¿
èŠãªå Žåãããã¯ã¹ã€ã³ã¢ãããŒãã䜿çšã§ããªããªããŸãã
ããã¯ã¹ã€ã³ã«ãã£ãŠå®£èšããããç¶æ
ãã¯ãå¥ã®ããã¯ã¹ã€ã³ãŸãã¯State
èªäœãšç«¶åããå¯èœæ§ããããŸãã
ããå
·äœçã«ã¯ã2ã€ã®ããã¯ã¹ã€ã³ãåãååã䜿çšããŠã¡ã³ããŒã宣èšãããšã競åãçºçããŸãã
ææªã®ã·ããªãªã§ã¯ã競åããã¡ã³ããŒãåãã¿ã€ãã®å Žåãããã¯ãµã€ã¬ã³ãã«å€±æããŸãã
ããã«ãããããã¯ã¹ã€ã³ã¯çæ³çã§ã¯ãªããå±éºãããŠçã®è§£æ±ºçã«ã¯ãªããŸããã
å¥ã®è§£æ±ºçã¯ã StreamBuilder
ïŒcoãšåããã¿ãŒã³ã䜿çšããããšã§ãã
ãã®ã³ã³ãããŒã©ãŒã管çããTextEditingControllerBuilder
ãŠã£ãžã§ãããäœæã§ããŸãã ããããã°ã build
ã¡ãœããã§èªç±ã«äœ¿çšã§ããŸãã
ãã®ãããªãŠã£ãžã§ããã¯éåžžã次ã®ããã«å®è£ ãããŸãã
class TextEditingControllerBuilder extends StatefulWidget {
const TextEditingControllerBuilder({Key key, this.builder}) : super(key: key);
final Widget Function(BuildContext, TextEditingController) builder;
<strong i="12">@override</strong>
_TextEditingControllerBuilderState createState() =>
_TextEditingControllerBuilderState();
}
class _TextEditingControllerBuilderState
extends State<TextEditingControllerBuilder> {
TextEditingController textEditingController;
<strong i="13">@override</strong>
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
properties.add(
DiagnosticsProperty('textEditingController', textEditingController));
}
<strong i="14">@override</strong>
void dispose() {
textEditingController.dispose();
super.dispose();
}
<strong i="15">@override</strong>
Widget build(BuildContext context) {
return widget.builder(context, textEditingController);
}
}
ãã®åŸããã®ããã«äœ¿çšãããŸãïŒ
class Example extends StatelessWidget {
<strong i="19">@override</strong>
Widget build(BuildContext context) {
return TextEditingControllerBuilder(
builder: (context, controller) {
return TextField(
controller: controller,
);
},
);
}
}
ããã«ãããããã¯ã¹ã€ã³ã§çºçããåé¡ã解決ãããŸãã ããããããã¯ä»ã®åé¡ãåŒãèµ·ãããŸãã
䜿çšæ³ã¯éåžžã«åé·ã§ãã ããã¯äºå®äžã1ã€ã®å€æ°å®£èšã«å¯ŸããŠ4è¡ã®ã³ãŒã+2ã¬ãã«ã®ã€ã³ãã³ãã§ãã
è€æ°å䜿çšãããå Žåãããã¯ããã«æªãããšã§ãã å¥ã®å
éšã«TextEditingControllerBuilder
ãäžåºŠäœæããããšã¯ã§ããŸãããããã«ããã³ãŒãã®å¯èªæ§ã倧å¹
ã«äœäžããŸãã
<strong i="28">@override</strong>
Widget build(BuildContext context) {
return TextEditingControllerBuilder(
builder: (context, controller1) {
return TextEditingControllerBuilder(
builder: (context, controller2) {
return Column(
children: <Widget>[
TextField(controller: controller1),
TextField(controller: controller2),
],
);
},
);
},
);
}
ããã¯ã2ã€ã®å€æ°ã宣èšããããã ãã®éåžžã«ã€ã³ãã³ããããã³ãŒãã§ãã
State
ãšElement
ã€ã³ã¹ã¿ã³ã¹ãè¿œå ãããããããªãŒããŒããããè¿œå ãããŸãã
build
å€ã§TextEditingController
ã䜿çšããããšã¯å°é£ã§ãã
State
ã©ã€ããµã€ã¯ã«ã§ãããã®ã³ã³ãããŒã©ãŒã«å¯ŸããŠäœããã®æäœãå®è¡ããå Žåã¯ããããã«ã¢ã¯ã»ã¹ããããã«GlobalKey
ãå¿
èŠã«ãªããŸãã äŸãã°ïŒ
class Example extends StatefulWidget {
<strong i="43">@override</strong>
_ExampleState createState() => _ExampleState();
}
class _ExampleState extends State<Example> {
final textEditingControllerKey =
GlobalKey<_TextEditingControllerBuilderState>();
<strong i="44">@override</strong>
void didUpdateWidget(Example oldWidget) {
super.didUpdateWidget(oldWidget);
if (something) {
textEditingControllerKey.currentState.textEditingController.clear();
}
}
<strong i="45">@override</strong>
Widget build(BuildContext context) {
return TextEditingControllerBuilder(
key: textEditingControllerKey,
builder: (context, controller) {
return TextField(controller: controller);
},
);
}
}
cc @dnfield @Hixie
èŠæ±ã«å¿ããŠãããã¯ããã¯ã«ãã£ãŠè§£æ±ºãããåé¡ãäœã§ãããã«ã€ããŠã®å®å
šãªè©³çŽ°ã§ãã
ãã¬ãŒã ã¯ãŒã¯å ã§ãããç°¡åã«ããããšãããšããŠãŒã¶ãŒãèããã¹ãè€éããå®éã«é ãããã®ã§ã¯ãªãããšå¿é ããŠããŸãã
ããçš®ã®abstract class Disposable
ç Žæ£ããå¿
èŠã®ããã¯ã©ã¹ã匷ãåä»ãããå Žåãã©ã€ãã©ãªã®äœæè
ã«ãšã£ãŠã¯ããã®äžéšãæ¹åãããå¯èœæ§ãããããã§ãã ãã®ãããªå Žåãããªãããã®ããã«åŸããŠãããªãã°ãããªãã¯ãã®ãããªããåçŽãªã¯ã©ã¹ãããç°¡åã«æžãããšãã§ããã¯ãã§ãïŒ
class AutomaticDisposingState<T> extends State<T> {
List<Disposable> _disposables;
void addDisposable(Disposable disposable) {
assert(!_disposables.contains(disposable));
_disposables.add(disposable);
}
<strong i="8">@override</strong>
void dispose() {
for (final Disposable disposable in _disposables)
disposable.dispose();
super.dispose();
}
}
ããã«ãããç¹°ãè¿ãããæ°è¡ã®ã³ãŒããåé€ãããŸãã ãããã°ããããã£çšã«åæ§ã®æœè±¡ã¯ã©ã¹ãäœæããããšããäž¡æ¹ãçµã¿åãããã¯ã©ã¹ãäœæããããšãã§ããŸãã åæç¶æ ã¯æ¬¡ã®ããã«ãªããŸãã
<strong i="12">@override</strong>
void initState() {
super.initState();
controller = TextEditingController(text: 'Hello world');
addDisposable(controller);
addProperty('controller', controller);
}
䜿ãæšãŠã¯ã©ã¹ã«ãã®ãããªã¿ã€ãã³ã°æ å ±ãæäŸããã®ãèŠéããŠããã ãã§ããïŒ
ãã¬ãŒã ã¯ãŒã¯å ã§ãããç°¡åã«ããããšãããšããŠãŒã¶ãŒãèããã¹ãè€éããå®éã«é ãããã®ã§ã¯ãªãããšå¿é ããŠããŸãã
ãŠã£ãžã§ããã¯ããŠãŒã¶ãŒãèããªããã°ãªããªãè€éããé ããŸãã
ãããæ¬åœã«åé¡ãªã®ãããããŸããã
çµå±ãããã奜ããªããã«å æ°å解ããã®ã¯ãŠãŒã¶ãŒæ¬¡ç¬¬ã§ãã
åé¡ã¯äœ¿ãæšãŠã ãã§ã¯ãããŸããã
ããã¯åé¡ã®æŽæ°éšåãå¿ããŸãã ã¹ããŒãžããžãã¯ã¯ãdidChangeDependenciesãdidUpdateWidgetãªã©ã®ã©ã€ããµã€ã¯ã«ã«äŸåããããšãã§ããŸãã
ããã€ãã®å ·äœçãªäŸïŒ
didChangeDependencies
å
ã«ããžãã¯ãæã€SingleTickerProviderStateMixinãsuper.build(context)
äŸåããAutomaticKeepAliveClientMixinãã¬ãŒã ã¯ãŒã¯ã«ã¯ãç¶æ ããžãã¯ãåå©çšãããäŸããããããããŸãã
ãããã¯ãæŽæ°ã¡ã«ããºã ã§ç¶æ ãåå©çšããæ¹æ³ã«ä»ãªããŸããã
ãããã圌ãã¯ããã«ããŒãã®éšåã§è¿°ã¹ãã®ãšåãåé¡ã«èŠããã§ããŸãã
ããã¯å€ãã®åé¡ãåŒãèµ·ãããŸãã
ããšãã°ãStackoverflowã§æãäžè¬çãªåé¡ã®1ã€ã¯ããå€æŽæã«ã«ãŒããããã·ã¥ããããªã©ã®å¯äœçšã«StreamBuilder
ã䜿çšããããšãã人ã
ã§ãã
ãããŠæçµçã«åœŒãã®å¯äžã®è§£æ±ºçã¯StreamBuilderããæåºãããããšã§ãã
ããã«ã¯ä»¥äžãå«ãŸããŸãã
ããã¯_å€ãã®äœæ¥_ã§ãããäºå®äžåå©çšã§ããŸããã
åé¡
State
ããžãã¯ãè€æ°ã®StatefulWidget
ãŸããã£ãŠåå©çšããããšã¯ããã®ããžãã¯ãè€æ°ã®ã©ã€ããµã€ã¯ã«ã«äŸåããããã«ãªããšããã«éåžžã«å°é£ã«ãªããŸããå žåçãªäŸã¯ã
TextEditingController
ïŒãã ããAnimationController
ãæé»ã®ã¢ãã¡ãŒã·ã§ã³ãªã©ïŒãäœæããããžãã¯ã§ãã ãã®ããžãã¯ã¯è€æ°ã®ã¹ãããã§æ§æãããŠããŸãã
State
å€æ°ãå®çŸ©ããŸãã
dart TextEditingController controller;
- ã³ã³ãããŒã©ãŒïŒéåžžã¯initStateå ïŒãäœæããŸããããã©ã«ãå€ã«ãªãå¯èœæ§ããããŸãã
dart <strong i="19">@override</strong> void initState() { super.initState(); controller = TextEditingController(text: 'Hello world'); }
State
ãç Žæ£ããããšãã«ãã³ã³ãããŒã©ãŒãç Žæ£ããŸããã
dart <strong i="24">@override</strong> void dispose() { controller.dispose(); super.dispose(); }
build
å ã®ãã®å€æ°ã§ããããããšãäœã§ãããŸãã- ïŒãªãã·ã§ã³ïŒãã®ããããã£ã
debugFillProperties
å ¬éããŸãïŒ
dart void debugFillProperties(DiagnosticPropertiesBuilder properties) { super.debugFillProperties(properties); properties.add(DiagnosticsProperty('controller', controller)); }
ããèªäœã¯è€éã§ã¯ãããŸããã åé¡ã¯ããã®ã¢ãããŒããæ¡åŒµããããšãã«å§ãŸããŸãã
äžè¬çãªFlutterã¢ããªã«ã¯æ°åã®ããã¹ããã£ãŒã«ããããå ŽåããããŸããããã¯ããã®ããžãã¯ãè€æ°åè€è£œãããããšãæå³ããŸãããã®ããžãã¯ãã©ãã«ã§ãã³ããŒããŠè²Œãä»ãããšãæ©èœãããŸãããã³ãŒãã«åŒ±ç¹ãçããŸãã
- æé ã®1ã€ãæžãçŽãã®ãå¿ããã¡ã§ãïŒ
dispose
åŒã³åºããå¿ãããªã©ïŒ- ã³ãŒãã«å€ãã®ãã€ãºãè¿œå ããŸã
ãªããããåé¡ãªã®ãç解ããã®ã«æ¬åœã«èŠåŽããŠããŸãã Flutterã¢ããªã±ãŒã·ã§ã³ãããããæžããã®ã§ãããããã»ã©åé¡ã«ã¯ãªããªãããã§ãã ææªã®å Žåã§ããããããã£ã宣èšããåæåããç Žæ£ãããããã°ããŒã¿ã«å ±åããã®ã¯4è¡ã§ãïŒéåžžãåæåããã®ãšåãè¡ã§å®£èšã§ãããããéåžžã¯å°ãªããªããŸããã¢ããªã¯äžè¬çã«ãããã°ããããã£ã«ç¶æ ãè¿œå ããããšãå¿é ããå¿ èŠã¯ãããŸããããããã®ãªããžã§ã¯ãã®å€ãã«ã¯ãç Žæ£ããå¿ èŠã®ããç¶æ ããããŸããïŒã
ããããã£ã¿ã€ãããšã®ããã¯ã¹ã€ã³ãæ©èœããªãããšã«åæããŸãã ç§ã¯ãã«ããŒãã¿ãŒã³ãè¯ããªãããšã«åæããŸãïŒããã¯æåéãäžèšã®ææªã®ã·ããªãªãšåãæ°ã®è¡ã䜿çšããŸãïŒã
NNBDã䜿çšãããšïŒå
·äœçã«ã¯ãã€ãã·ãšãŒã¿ãŒãthis
åç
§ã§ããããã«late final
䜿çšïŒã次ã®ãããªããšãã§ããŸãã
typedef Initializer<T> = T Function();
typedef Disposer<T> = void Function(T value);
mixin StateHelper<T extends StatefulWidget> on State<T> {
bool _active = false;
List<Property<Object>> _properties = <Property<Object>>[];
<strong i="8">@protected</strong>
void registerProperty<T>(Property<T> property) {
assert(T != Object);
assert(T != dynamic);
assert(!_properties.contains(property));
_properties.add(property);
if (_active)
property._initState();
}
<strong i="9">@override</strong>
void initState() {
_active = true;
super.initState();
for (Property<Object> property in _properties)
property._initState();
}
<strong i="10">@override</strong>
void dispose() {
for (Property<Object> property in _properties)
property._dispose();
super.dispose();
_active = false;
}
void debugFillProperties(DiagnosticPropertiesBuilder properties) {
super.debugFillProperties(properties);
for (Property<Object> property in _properties)
property._debugFillProperties(properties);
}
}
class Property<T> {
Property(this.owner, this.initializer, this.disposer, [ this.debugName ]) {
owner.registerProperty(this);
}
final StateHelper<StatefulWidget> owner;
final Initializer<T> initializer;
final Disposer<T> disposer;
final String debugName;
T value;
void _initState() {
if (initializer != null)
value = initializer();
}
void _dispose() {
if (disposer != null)
disposer(value);
value = null;
}
void _debugFillProperties(DiagnosticPropertiesBuilder properties) {
properties.add(DiagnosticsProperty(debugName ?? '$T property', value));
}
}
ããªãã¯ããããã®ããã«äœ¿ãã§ãããïŒ
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
<strong i="14">@override</strong>
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with StateHelper<MyHomePage> {
late final Property<int> _counter = Property<int>(this, null, null);
late final Property<TextEditingController> _text = Property<TextEditingController>(this,
() => TextEditingController(text: 'button'),
(TextEditingController value) => value.dispose(),
);
void _incrementCounter() {
setState(() {
_counter.value += 1;
});
}
<strong i="15">@override</strong>
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'You have pushed the ${_text.value.text} this many times:',
),
Text(
'${_counter.value}',
style: Theme.of(context).textTheme.headline4,
),
TextField(
controller: _text.value,
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: Icon(Icons.add),
),
);
}
}
æ¬åœã«ç©äºãè¯ãããããã«ã¯èŠããŸããã ãŸã 4è¡ã§ãã
ãŠã£ãžã§ããã¯ããŠãŒã¶ãŒãèããªããã°ãªããªãè€éããé ããŸãã
圌ãã¯äœãé ããŸããïŒ
åé¡ã¯è¡æ°ã§ã¯ãªãããããã®è¡ãäœã§ãããã§ãã
StreamBuilder
ã¯ã stream.listen
+ setState
+ subscription.close
ãšã»ãŒåãè¡æ°ã«ãªãå¯èœæ§ããããŸãã
ãããã StreamBuilder
ãæžãããšã¯ãããã°ãäœã®åçã䌎ããã«è¡ãããšãã§ããŸãã
ãã®éçšã§èµ·ããããééãã¯ãããŸããã ããã¯åã«ãã¹ããªãŒã ãæž¡ãããããããŠã£ãžã§ãããæ§ç¯ãããã ãã§ãã
ã³ãŒããæåã§äœæããã«ã¯ãããã«å€ãã®èæ ®äºé ãå¿ èŠã§ãã
StreamBuilder
ã䜿çšãããšãã¹ããªãŒã ããªãã¹ã³ããããã®åäœãã¹ããäœæããå¿
èŠããªããªããåé·ã«ãªããŸãã ããããåžžã«æåã§æžããšãééããç¯ãå¯èœæ§ããããŸãã圌ãã¯äœãé ããŸããïŒ
Future
ãåãæ¿ããããžãã¯ãã subscription.close()
ããªãããšãèãããšãããªãè€éã§ããã¢ããªã¯éåžžããããã°ããããã£ã«ç¶æ ãè¿œå ããããšãå¿é ããå¿ èŠã¯ãããŸãã
debugFillPropertiesã¡ãœãããç¶æããè€éãã«å¯ŸåŠããããªãã®ã§ãããããŸããã
ããããéçºè
ã«ãç®±ããåºããŠããã«äœ¿çšã§ããããã«ããŸããïŒãã¹ãŠã®ãã©ã¡ãŒã¿ãŒãšç¶æ
ããããã£ãFlutterã®devtoolã§å©çšå¯èœã§ãããïŒã 圌ãã¯ããèšãã ãããšç¢ºä¿¡ããŠããŸã
å€ãã®äººããReactã®devtoolãšçã«åçã®ãã®ãæãã§ããããšãç§ã«è¡šæããŠããŸããã Flutterã®devtoolã¯ãŸã ãããŸããã
Reactã§ã¯ããŠã£ãžã§ããã®ãã¹ãŠã®ç¶æ
ãšãã®ãã©ã¡ãŒã¿ãŒã確èªããäœãããã«ç·šéã§ããŸãã
åæ§ã«ã provider
+ä»ã®ããã±ãŒãžã䜿çšãããšãããã©ã«ãã§ã¯ãäœãããªããŠãã¢ããªã±ãŒã·ã§ã³ã®ç¶æ
å
šäœã衚瀺ããããšèšã£ããšãã人ã
ã¯éåžžã«é©ããŠããŸããïŒãã®åä»ãªdevtoolãã°ãæ³ãšããŠïŒ
ç§ã¯FutureBuilderã®å€§ãã¡ã³ã§ã¯ãªãããšãèªããªããã°ãªããŸããã人ã ã¯ãã€Futureãããªã¬ãŒããããèããŠããªããããå€ãã®ãã°ãçºçããŸãã ãµããŒãããããã®ã¯ç¡çã¯ãªããšæããŸãã StreamBuilderã¯å€§äžå€«ã ãšæããŸãããStreamsèªäœã¯è€éããããšæããŸãïŒäžèšã®ã³ã¡ã³ãã§è¿°ã¹ãããã«ïŒã®ã§...
ãªã誰ãããã¥ã€ãŒã³ã®äœæã®è€éãã«ã€ããŠèããªããã°ãªããªãã®ã§ããïŒ
ListViewã¯ããŠã£ãžã§ãããããŠã³ãããããžãã¯ã衚瀺ã©ããã«é ããŠããããã§ã¯ãããŸããã ããã¯APIã®å€§ããªéšåã§ãã
åé¡ã¯è¡æ°ã§ã¯ãªãããããã®è¡ãäœã§ãããã§ãã
ç§ã¯ããã§ã®æžå¿µãæ¬åœã«ç解ããŠããŸããã ç·ã¯åçŽãªå®åæã®ããã«èŠããŸãã ã¢ãã宣èšããã¢ããåæåããã¢ããåŠåããŸãã è¡æ°ã§ã¯ãªãå Žåãäœãåé¡ãªã®ã§ããããã
FutureBuilderã«åé¡ãããããšã«åæããŸãã
å°ã話é¡ããå€ããŠããŸãããéçºã§ã¯ãFlutterãæ°ç§ããšã«åœã®ããããªããŒããããªã¬ãŒããå¿ èŠãããããšããå§ãããŸãã ããã«ãããFutureBuilderãããŒããã®ä»å€ãã®èª€çšãæµ®ã圫ãã«ãªããŸãã
ãªã誰ãããã¥ã€ãŒã³ã®äœæã®è€éãã«ã€ããŠèããªããã°ãªããªãã®ã§ããïŒ
ListViewã¯ããŠã£ãžã§ãããããŠã³ãããããžãã¯ã衚瀺ã©ããã«é ããŠããããã§ã¯ãããŸããã ããã¯APIã®å€§ããªéšåã§ãã
ç§ãã¡ã¯ããã«åæããŸãã ç§ã®ãã€ã³ãã¯ãããã¯ãè¡ãããšã¯TweenAnimationBuilder
/ AnimatedContainer
/ ...ãè¡ãããšãšå³å¯ã«åçã§ããããããããžãã¯ãé ãããšããããã¯ã®ãããªãã®ãæ¹å€ããããšã¯ã§ããªããšããããšã§ããã
ããžãã¯ã¯é ãããŠããŸãã
çµå±ãã¢ãã¡ãŒã·ã§ã³ã¯è¯ãæ¯èŒã ãšæããŸãã ã¢ãã¡ãŒã·ã§ã³ã«ã¯ãæé»ç察æ瀺çãšãããã®æŠå¿µããããŸãã
æé»ã®ã¢ãã¡ãŒã·ã§ã³ã¯ããã®ã·ã³ãã«ããæ§æå¯èœæ§ãèªã¿ãããããæãããŠããŸãã
æ瀺çãªã¢ãã¡ãŒã·ã§ã³ã¯ããæè»ã§ãããããè€éã§ãã
ãã®æŠå¿µãã¹ããªãŒã ã®ãªã¹ãã³ã°ã«å€æãããšã StreamBuilder
ã¯_æé»ã®ãªã¹ãã³ã°_ã§ããã stream.listen
ã¯_æ瀺çãªãªã¹ãã³ã°_ã§ãã
ããå
·äœçã«ã¯ã StreamBuilder
ã䜿çšãããšãã¹ããªãŒã ãå€æŽãããã·ããªãªãåŠçããããšãå¿ãããããµãã¹ã¯ãªãã·ã§ã³ãéããããšãå¿ãããããããšã¯ã§ããŸããã
è€æ°ã®StreamBuilder
çµã¿åãããããšãã§ããŸã
stream.listen
ã¯å°ãé«åºŠã§ããšã©ãŒãçºçãããããªã£ãŠããŸãã
ãã«ããŒã¯ãã¢ããªã±ãŒã·ã§ã³ãç°¡çŽ åããããã«åŒ·åã§ãã
ãããã以åã«åæããããã«ãBuilderãã¿ãŒã³ã¯çæ³çã§ã¯ãããŸããã æžãããšã䜿ãããšãåé·ã§ãã
ãã®åé¡ãšããã¯ã解決ãããã®ã¯ã* Buildersã®ä»£æ¿æ§æã«é¢ãããã®ã§ã
ããšãã°ã flutter_hooks
ã¯ã FutureBuilder
ããã³StreamBuilder
ãšå³å¯ã«åçã§ãã
Widget build(context) {
final AsyncSnapshot<T> snapshot = useStream(stream);
}
ç¶ããŠã AnimatedContainer
ã¯useAnimatedSize
/ useAnimatedDecoractedBox
/ ...ã§è¡šãããšãã§ããŸãã
double opacity;
Widget build(context) {
final double animatedOpacity = useAnimatedDouble(opacity, duration: Duration(milliseconds: 200));
return Opacity(
opacity: animatedOpacity,
child: ...,
);
}
ç§ã®ãã€ã³ãã¯ããè«çãé ãããšããããã¯ã®ãããªãã®ãæ¹å€ããããšã¯ã§ããªããšããããšã§ããã
ããã¯è°è«ã§ã¯ãããŸããã è°è«ã¯ãéçºè ãèããã¹ãè«ç
éçºè ãèããã¹ããã®ãããªããžãã¯ã®äŸã¯ãããŸããïŒ
ããšãã°ãTextEditingControllerã®ææè ïŒäœæè ãå»æ£è ïŒã®ããã«ã
ãã®ã³ãŒãã®ããã«ïŒ
Widget build(context) {
final controller = useTextEditingController();
final focusNode = useFocusNode();
}
ããã¯ããããäœæãããããåŠåããŸãã
ããã«ã€ããŠäœãäžæ確ãªã®ãããããŸããã
ã¯ããæ£ç¢ºã«ã ãã®ã³ãŒãã§ã®ã³ã³ãããŒã©ãŒã®ã©ã€ããµã€ã¯ã«ãäœã§ãããããããŸããã åå¥ã¹ã³ãŒããçµäºãããŸã§ç¶ããŸããïŒ åœå®¶ã®çæ¶¯ïŒ ä»ã«äœããããŸããïŒ èª°ããããææããŠããŸããïŒ ç§ããããä»ã®èª°ãã«æž¡ããå Žåã圌ãã¯æææš©ãååŸã§ããŸããïŒ ããã¯ãã³ãŒãèªäœã§ã¯æããã§ã¯ãããŸããã
ããªãã®è°è«ã¯ãå®éã®åé¡ã§ã¯ãªããããã¯ãäœãããã®ãã«ã€ããŠã®ç解ã®æ¬ åŠã«ãã£ãŠåŒãèµ·ããããŠããããã§ãã
ãããã®è³ªåã«ã¯ããã¹ãŠã®ããã¯ãšäžèŽããæ確ã«å®çŸ©ãããåçããããŸãã
ãã®ã³ãŒãã§ã®ã³ã³ãããŒã©ãŒã®ã©ã€ããµã€ã¯ã«ãäœã§ãããããããŸãã
ãŸããããã«ã€ããŠèããå¿ èŠããããŸããã ããã¯ãã¯ãéçºè ã®è²¬ä»»ã§ã¯ãããŸããã
åå¥ã¹ã³ãŒããçµäºãããŸã§ç¶ããŸããïŒ åœå®¶ã®ç涯
åœå®¶ã®ç涯
誰ããããææããŠããŸããïŒ
ããã¯ã¯ã³ã³ãããŒã©ãŒãææããŸãã ã³ã³ãããŒã©ãææããŠããã®ã¯useTextEditingController
ã®APIã®äžéšã§ãã
ããã¯useFocusNode
ã useScrollController
ã useAnimationController
ã..ã«é©çšãããŸãã
ããæå³ã§ããããã®è³ªåã¯StreamBuilder
åœãŠã¯ãŸããŸãã
äžè¬çã«ãããªãã¯èããããšãã§ããŸãïŒ
final value = useX(argument);
å³å¯ã«åçã®ãã®ãšããŠïŒ
XBuilder(
argument: argument,
builder: (context, value) {
},
);
ãããã¯åãã«ãŒã«ãšåãåäœãããŸãã
éçºè ã®è²¬ä»»ã§ã¯ãªããªããŸãã
åºæ¬çã«ãããããã§ã®æèŠã®çžéã ãšæããŸãã æ確ã§ã¯ãªãå®çŸ©ãããåç¶æéãæã€å€ãè¿ãé¢æ°ã®ãããªAPIãæã€ããšã¯ãIMHOã§ããããã®å€ãã¯ããŒãžã£ãŒã«æž¡ãããšã«åºã¥ãAPIãšã¯æ ¹æ¬çã«å€§ããç°ãªããŸãã
ãã®ã¹ã¿ã€ã«ã䜿çšããããã±ãŒãžãäœæãã人ã«ã¯åé¡ãããŸããããã³ã¢ãã©ãã¿ãŒAPIã«å«ãããçš®é¡ãšã¯éã®ã¹ã¿ã€ã«ã§ãã
@Hixie
@rrousselGitãèšã£ãŠããã®ã¯ããããã¯åããã®ã§ãããšããããšã§ã¯ãªããã©ã€ããµã€ã¯ã«ã«é¢ããŠãåãã«ãŒã«ãšåãåäœããæã£ãŠãããšããããšã ãšæããŸããïŒ æ£ããïŒ
ãã ããåãåé¡ã解決ããããšã¯ã§ããŸããã
ç§ã¯ããã§ééã£ãŠãããããããŸããããæšå¹Žã®ç§ã«ãã©ãã¿ãŒãè©ŠããŠã¿ããšã1ã€ã®ãŠã£ãžã§ããã«ãããã®ãã«ããŒã3ã€å¿
èŠã ã£ããšããããå€ãã®ãã¹ããå¿
èŠã ã£ããšæããŸãã 3ã€ã®ããã¯ïŒ3è¡ïŒãšæ¯èŒããŠã
ãŸãã ããã¯ã¯æ§æå¯èœã§ãããããè€æ°ã®ããã¯ã§æ§æãããç¶æ
ããžãã¯ãå
±æããå¿
èŠãããå Žåã¯ãä»ã®ããã¯ãšããã€ãã®è¿œå ããžãã¯ã䜿çšããæ°ããããã¯ãäœæãã1ã€ã®æ°ããããã¯ã䜿çšããããšãã§ããŸãã
ãŠã£ãžã§ããéã§ç¶æ ããžãã¯ãç°¡åã«å ±æãããããªãã®ã¯ã2019幎ã®ãã©ãã¿ãŒç§ãè©Šãããšãã«ç§ãèŠéããŠãããã®ã§ããã
ãã¡ãããä»ã«ãå€ãã®å¯èœãªè§£æ±ºçãããå¯èœæ§ããããŸãã å€åããã¯ãã§ã«è§£æ±ºãããŠããŠãç§ã¯ãããããã¥ã¡ã³ãã§èŠã€ããããŸããã§ããã
ããããããã§ãªãå Žåã第äžçŽåžæ°ãšããŠå©çšå¯èœãªå Žåãããã¯ãåãåé¡ã®å¥ã®è§£æ±ºçã®ãããªãã®ãããã°ãéçºã倧å¹
ã«ã¹ããŒãã¢ããããããã«ã§ããããšã¯ãããããããŸãã
OPãèšåããŠããããã«ãããããçš®é¡ã®åé¡ããããã«ããŒã¢ãããŒãã䜿çšããããšãç§ã¯çµ¶å¯Ÿã«ææ¡ããŠããŸããã ç§ãææ¡ããã®ã¯ãinitState / disposeã䜿çšããããšã§ãã ãªããããåé¡ãªã®ãããããããŸããã
https://github.com/flutter/flutter/issues/51752#issuecomment-664787791ã®ã³ãŒãã«ã€ããŠäººã ãã©ã®ããã«æããŠããã®ãèå³ããã
@Hixieããã¯ã¯ãã©ã€ããµã€ã¯ã«ãåäžã®é¢æ°åŒã³åºãã«åºåããããã䜿ãuseAnimationController
ããã«ããã¯ã䜿çšããå ŽåãinitStateã«ã€ããŠèããŠç Žæ£ããå¿
èŠã¯ãããŸããã ããã¯éçºè
ãã責任ãåãé€ããŸãã äœæãããã¹ãŠã®ã¢ãã¡ãŒã·ã§ã³ã³ã³ãããŒã©ãŒãç Žæ£ãããã©ãããå¿é
ããå¿
èŠã¯ãããŸããã
initState
ãšdispose
ã¯ã1ã€ã®ããšã«ã¯åé¡ãããŸããããè€æ°ã®ç°ãªãã¿ã€ãã®ç¶æ
ã远跡ããå¿
èŠãããããšãæ³åããŠã¿ãŠãã ããã ããã¯ã¯ãã¯ã©ã¹ã®ã©ã€ããµã€ã¯ã«ã«åæ£ãããã®ã§ã¯ãªããæœè±¡åã®è«çåäœã«åºã¥ããŠæ§æãããŸãã
ããªããæ±ããŠããã®ã¯ãæ¯åæåã§ãšãã§ã¯ããåŠçã§ããã®ã«ããªãé¢æ°ãããã®ãââãšããããšãšåãã ãšæããŸãã ç§ã¯ãããå®å
šã«åãã§ã¯ãªãããšã«åæããŸãããããã¯ãããã䌌ãŠããããã«æããŸãã 以åã«ããã¯ã䜿çšããããšããªãããã§ãã®ã§ãåé¡ã¯ããŸãæçœã§ã¯ãªãããã§ãããããã£ãŠãããããflutter_hooks
ããã±ãŒãžã䜿çšããŠãããã¯ã䜿çšããŠäžå°èŠæš¡ã®ãããžã§ã¯ããå®è¡ããããšããå§ãããŸãããããã©ã®ããã«æãããã ç§ã¯ãããããããç¹ã§èšããŸããFlutterã®ãŠãŒã¶ãŒãšããŠãä»ã®äººãšåãããã«ãããã¯ã解決çãæäŸãããããã®åé¡ã«ééããŸããã ãããã®åé¡ãæ¬åœã«ç§ãã¡ã«ååšããããšãããªãã«çŽåŸãããæ¹æ³ãããããŸããããã£ãšè¯ãæ¹æ³ããããã©ããç§ãã¡ã«ç¥ãããŠãã ããã
Reactã®èŠ³ç¹ããããã€ãã®èããè¿œå ããŸãã
é¢é£æ§ããªãå Žåã¯ã容赊ãã ããããã ããããã¯ã«ã€ããŠã®èãæ¹ãç°¡åã«èª¬æããããšæããŸãã
ããã¯ã¯ééããªãç©ããé ããŠãããã ãŸãã¯ããããã©ã®ããã«èŠããã«å¿ããŠãããããã«ãã»ã«åããŸãã ç¹ã«ããããã¯å±æçãªç¶æ ãšå¹æãã«ãã»ã«åããŸãïŒç§ãã¡ã®ãå¹æãã¯ã䜿ãæšãŠããšåããã®ã ãšæããŸãïŒã ãæé»æ§ããšã¯ãåŒã³åºãããã³ã³ããŒãã³ãã«ã©ã€ãã¿ã€ã ãèªåçã«ä»å ããããšã§ãã
ãã®æé»æ§ã¯ãã¢ãã«ã«åºæã®ãã®ã§ã¯ãããŸããã ã³ã³ããŒãã³ãèªäœããã«ã¹ã¿ã ããã¯å
šäœãåããªããã£ãããã¯ã«è³ããŸã§ããã¹ãŠã®åŒã³åºãã«åŒæ°ãæ瀺çã«ã¹ã¬ããåãããŠããããšãæ³åã§ããŸãã ãããå®éã«ã¯ããã€ãºãå€ããå®éã«ã¯åœ¹ã«ç«ããªãããšãããããŸããã ãã®ãããçŸåšå®è¡äžã®ã³ã³ããŒãã³ããæé»çãªã°ããŒãã«ç¶æ
ã«ããŸããã ããã¯ãã³ãŒãã§errorHandlerFrame
ãæž¡ã代ããã«ãVMã®throw
ãæãè¿ãcatch
ãããã¯ãäžåãã«æ€çŽ¢ããæ¹æ³ã«äŒŒãŠããŸãã
ããŠãããã¯ãããã®äžã«æé»ã®é ãããç¶æ ãæã€é¢æ°ã§ããããã¯æªãããã«èŠããŸããïŒ ããããReactã§ã¯ãäžè¬çãªã³ã³ããŒãã³ããããã§ãã ãããã³ã³ããŒãã³ãã®èŠç¹ã§ãã ãããã¯ãæå¹æéãé¢é£ä»ããããŠããé¢æ°ã§ãïŒUIããªãŒå ã®äœçœ®ã«å¯Ÿå¿ããŸãïŒã ã³ã³ããŒãã³ãèªäœãç¶æ ã«é¢ããŠãããã¬ã³ã§ã¯ãªãçç±ã¯ãã©ã³ãã ãªã³ãŒãããã³ã³ããŒãã³ããåŒã³åºãã ãã§ã¯ãªãããã§ãã ä»ã®ã³ã³ããŒãã³ãããããããåŒã³åºããŸãã ãããã£ãŠãUIã³ãŒãã®ã³ã³ããã¹ãã«ãšã©ãŸãããããããã®åç¶æéã¯çã«ããªã£ãŠããŸãã
ãã ãããã¹ãŠã®åé¡ãã³ã³ããŒãã³ãã®åœ¢ãããŠããããã§ã¯ãããŸããã ã³ã³ããŒãã³ãã¯ãç¶æ ãšå¹æãããã³ããªãŒã®äœçœ®ã«é¢é£ä»ããããåç¶æéãšãã2ã€ã®æ©èœãçµã¿åããããã®ã§ãã ããããæåã®èœåã¯ããèªäœã§åœ¹ç«ã€ããšãããããŸããã é¢æ°ãã³ãŒããã«ãã»ã«åã§ããã®ã§äžè¬çã«åœ¹ç«ã€ã®ãšåãããã«ãããªãŒã«æ°ããããŒããäœæããªããŠããç¶æ ãšå¹æã®ãã³ãã«ãã«ãã»ã«åïŒããã³åå©çšïŒã§ããããªããã£ãããããŸããã§ããã ãããããã¯ã§ãã ã³ã³ããŒãã³ã=ããã¯+è¿ãããUIã
å ã»ã©ç³ãäžããããã«ãã³ã³ããã¹ãç¶æ ãé ãä»»æã®é¢æ°ã¯æãã§ãã ãããããªã³ã¿ãŒãä»ããŠèŠåãæœè¡ããçç±ã§ãã ããã¯ã«ã¯ãè²ãããããŸãâããã¯ã䜿çšããå Žåãé¢æ°ã¯ããã¯ã§ããããŸãã ãŸãããªã³ã¿ãŒã¯ãã³ã³ããŒãã³ããŸãã¯ä»ã®ããã¯ã®ã¿ãããã¯ã䜿çšã§ããããã«åŒ·å¶ããŸãã ããã«ãããä»»æã®é¢æ°ãã³ã³ããã¹ãUIã®ç¶æ ãé ããšããåé¡ã解æ¶ãããŸããããã¯ãããããã³ã³ããŒãã³ãèªäœãããæé»çã§ã¯ãªããªã£ãããã§ãã
æŠå¿µçã«ã¯ãããã¯åŒã³åºããåçŽãªé¢æ°åŒã³åºããšã¯èŠãªããŸããã useState()
use State()
ããã«ãæ§æãããã°ã 代æ°å¹æãåããããã¯ã®ãããªãã®ãã¢ãã«åã§ããŸãã ãããã£ãŠããã®æå³ã§ã¯ããããã¯éåžžã®é¢æ°ã«ãªããŸãããç¶æ
ãã䜿çšããããšããäºå®ã¯ãåã·ã°ããã£ã®äžéšã«ãªããŸãã 次ã«ãReactèªäœããã®ãšãã§ã¯ãã®ããã³ãã©ãŒããšèããããšãã§ããŸãã ãšã«ãããããã¯éåžžã«çè«çã§ãããããã°ã©ãã³ã°ã¢ãã«ã®èŠ³ç¹ããå
è¡æè¡ãææããããšæããŸããã
å®éã«ã¯ãããã«ã¯ããã€ãã®ããšããããŸãã ãŸããããã¯ã¯Reactã®ãè¿œå ã®ãAPIã§ã¯ãªãããšã«æ³šæããŠãã ããã ãããã¯ãçŸæç¹ã§ã³ã³ããŒãã³ããäœæãããã
ããããå¯èœã«ãããã®ã«é¢ããŠã¯ãéèŠãªæ©èœã¯ãç¶æ
+å¹æçãªããžãã¯ãã«ãã»ã«åããéåžžã®é¢æ°åæã®å Žåãšåãããã«ããããã§ãŒã³åããæ©èœã ãšæããŸãã ããªããã£ãã¯æ§æããããã«èšèšãããŠããããã useState()
ãããªããã¯åºåãååŸãããããã«ã¹ã¿ã useGesture(state)
ãžã®å
¥åãšããŠæž¡ãããããããã€ãã®ã«ã¹ã¿ã useSpring(gesture)
ãžã®å
¥åãšããŠæž¡ãããšãã§ããŸããåé³¥ç¶ã®å€ãäžããå°ããªãã¢ãšãããã¯ãšã¯äœããç°¡åã«èŠçŽããèšäºã§ãã
ããã¯å®åæãæžããããšã§ã¯ãªããã¹ããŒããã«ã«ãã»ã«åããžãã¯ã®ãã€ãã©ã€ã³ãåçã«æ§æããæ©èœ
ããã圹ã«ç«ã£ããã©ããã¯ããããŸããããããã°ã©ãã³ã°ã¢ãã«ã«äœããã®èŠç¹ãäžããããšãé¡ã£ãŠããŸãã
ä»ã®è³ªåã«ãçãããŸãã
OPãèšåããŠããããã«ãããããçš®é¡ã®åé¡ããããã«ããŒã¢ãããŒãã䜿çšããããšãç§ã¯çµ¶å¯Ÿã«ææ¡ããŠããŸããã ç§ãææ¡ããã®ã¯ãinitState / disposeã䜿çšããããšã§ãã ãªããããåé¡ãªã®ãããããããŸããã
ïŒ51752ïŒã³ã¡ã³ãïŒã®ã³ãŒãã«ã€ããŠäººã ãã©ã®ããã«æããŠããã®ãèå³ããããŸãã initState / disposeãããåªããŠãããšã¯æããŸããããããã¯ã奜ããªäººã¯ããã奜ãã§ããïŒ ããã¯ã¯è¯ãã§ããïŒ æªãïŒ
late
ããŒã¯ãŒãã¯ç¶æ³ãæ¹åããŸãããããã§ãããã€ãã®åé¡ããããŸãã
ãã®ãããªProperty
ã¯ãèªå·±å®çµåã®ç¶æ
ããŸãã¯æéã®çµéãšãšãã«å€åããå¯èœæ§ã®ãããã©ã¡ãŒã¿ãŒã«äŸåããªãç¶æ
ã«åœ¹ç«ã€å ŽåããããŸãã ãã ããç¶æ³ãç°ãªããšäœ¿ãã¥ãããªãå ŽåããããŸãã
ããæ£ç¢ºã«ã¯ããæŽæ°ãéšåããããŸããã
ããšãã°ã StreamBuilder
ãããšããªãã¹ã³ãããã¹ããªãŒã ã¯æéã®çµéãšãšãã«å€åããå¯èœæ§ããããŸãã ãã ãããªããžã§ã¯ãã¯1åããåæåãããªããããããã§ãã®ãããªããšãå®è£
ããç°¡åãªè§£æ±ºçã¯ãããŸããã
åæ§ã«ãããã¯ã«ã¯ãŠã£ãžã§ããã®Key
ãšåçã®ãã®ããããŸããããã«ãããããŒãå€æŽããããšãã«ç¶æ
ã®äžéšãç Žæ£ãããåäœæãããå¯èœæ§ããããŸãã
ãã®äŸã¯useMemo
ãããã¯ãªããžã§ã¯ãã®ã€ã³ã¹ã¿ã³ã¹ããã£ãã·ã¥ããããã¯ã§ãã
ããŒãšçµã¿åãããŠã useMemo
ã䜿çšããŠæé»çãªããŒã¿ãã§ãããè¡ãããšãã§ããŸãã
ããšãã°ããŠã£ãžã§ãããã¡ãã»ãŒãžIDãåä¿¡ããå ŽåããããŸããããã䜿çšããŠãã¡ãã»ãŒãžã®è©³çŽ°ãååŸããŸãã ãã ãããã®ã¡ãã»ãŒãžIDã¯æéã®çµéãšãšãã«å€åããå¯èœæ§ãããããã詳现ãåååŸããå¿
èŠãããå ŽåããããŸãã
useMemo
å Žåã次ã®ããã«ãªããŸãã
String messageId;
Widget build(context) {
final Future<Message> message = useMemo(() => fetchMessage(messageId), [messageId]);
}
ãã®å Žåãbuildã¡ãœããã10ååŒã³åºãããŠãã messageId
ãå€ãããªãéããããŒã¿ã®ãã§ããã¯å床å®è¡ãããŸããã
ãã ãã messageId
ãå€æŽããããšãæ°ããFuture
ãäœæãããŸãã
çŸåšã®ç¶æ
ã®flutter_hooks
ãããŒãã®ããã«æŽç·ŽãããŠãããšã¯æããªãããšã¯æ³šç®ã«å€ããŸãã ç§ã®å®è£
ã¯ãæ¬æ Œçãªã¢ãŒããã¯ãã£ãšãããããPOââCã§ãã
ããããStatefulWidgetsã®ã³ãŒãã®åå©çšæ§ã«åé¡ããããšç§ã¯ä¿¡ããŠããŸãã
ã©ãã«ãããã¯èŠããŠããŸããããçæ³çãªäžçã®ããã¯ã¯ã async*
ãšsync*
é£ã«ããã«ã¹ã¿ã é¢æ°çºçåšã§ãããšææ¡ããããšãèŠããŠããŸããããã¯ãDanãuse State
ææ¡ãããã®ãšäŒŒãŠããå¯èœæ§ããããŸãã useState
ã§ã¯ãªãuse State
useState
@gaearon
ããã¯å®åæãæžããããšã§ã¯ãªããã¹ããŒããã«ã«ãã»ã«åããžãã¯ã®ãã€ãã©ã€ã³ãåçã«æ§æããæ©èœã«ã€ããŠã§ããããšã匷調ããããšæããŸãã
ããã¯ããã§è°è«ãããŠããåé¡ã§ã¯ãããŸããã ããªãã説æããããšãå®è¡ã§ããªãããšã«ã€ããŠè©±ãããã«ãå¥ã®ãã°ãæåºããããšããå§ãããŸãã ïŒããã¯éåžžã«ç°ãªãåé¡ã®ããã«èãããŸãããæ£çŽãªãšãããããã§èª¬æããåé¡ããã説åŸåããããŸããïŒãã®ãã°ã¯ãç¹ã«ããžãã¯ã®äžéšãåé·ãããããšã«é¢ãããã®ã§ãã
ãããã圌ã¯æ£ããã§ããæ··ä¹±ãããããããªãã®ã¯ç§ã®èšèé£ãã§ãã
åã«è¿°ã¹ãããã«ãããã¯ã³ãŒãã®è¡æ°ã§ã¯ãªããã³ãŒãã®è¡èªäœã§ãã
ããã¯ç¶æ ã®å æ°å解ã«ã€ããŠã§ãã
ãã®ãã°ã¯ããç¶æ ããžãã¯ã®åå©çšãåé·/å°é£ãããããšããåé¡ãšãinitStateã§å®£èšããã³ãŒããå¿ èŠãªããããã£ãããå Žåã«ãç¶æ ã«ã³ãŒããå€ããããšããåé¡ã«ã€ããŠéåžžã«æ確ã§ããç Žæ£ããdebugFillPropertiesã§ã æ°ã«ãªãåé¡ãäœãéãå Žåã¯ããã®åé¡ã説æããæ°ãããã°ãæåºããããšããå§ãããŸãã
解決ãããåé¡ãå®å šã«ç解ãããŸã§ãããã¯ïŒãŸãã¯ä»»æã®è§£æ±ºçïŒãå¿ããããšã匷ããå§ãããŸãã åé¡ãæ確ã«ç解ããããšã«ãã£ãŠã®ã¿ãæ°ããæ©èœãæ¯æãã説åŸåã®ããè°è«ãæ確ã«ããããšãã§ããŸãããªããªãããããã解決ããåé¡ã«å¯ŸããŠæ©èœãè©äŸ¡ããå¿ èŠãããããã§ãã
ãã®æãç§ããã®å·ã§èšã£ãããšãããªãã¯èª€è§£ããŠãããšæããŸãã
åé¡ã¯æ±ºããŠå®åæã§ã¯ãªããåå©çšæ§ã§ãã
ãã€ã©ãŒãã¬ãŒãã¯åå©çšæ§ã®åé¡ã®çµæã§ãããåå ã§ã¯ãããŸãã
ãã®åé¡ã®èª¬æã¯æ¬¡ã®ãšããã§ãã
ç¶æ ããžãã¯ãåå©çš/æ§æãããå ŽåããããŸãã ãã ãã䜿çšå¯èœãªãªãã·ã§ã³ã¯ãããã¯ã¹ã€ã³ããã«ããŒããŸãã¯åå©çšããªããã®ããããã§ãããããã«ã¯ãã¹ãŠç¬èªã®åé¡ããããŸãã
æ¢åã®ãªãã·ã§ã³ã®åé¡ã¯å®åæã«é¢é£ããŠããå¯èœæ§ããããŸãããç§ãã¡ã解決ããããšããŠããåé¡ã¯ããã§ã¯ãããŸããã
Buildersã®å®åæãæžããããšã¯1ã€ã®ãã¹ïŒããã¯ãè¡ãããšã§ãïŒã§ãããå¥ã®ãã¹ãããå ŽåããããŸãã
ããšãã°ãç§ããã°ããææ¡ãããã£ãã®ã¯ã次ã®ãããªã¡ãœãããè¿œå ããããšã§ããã
context.onDidChangeDependencies(() {
});
context.onDispose(() {
});
ãããããããã«ã¯ç¬èªã®åé¡ããããåé¡ãå®å šã«è§£æ±ºããããã§ã¯ãªãã®ã§ãç§ã¯ããŸããã§ããã
@rrousselGit ãåé¡ãããé©åã«åæ ããããã«ãããã®äžéšã«ããå ã®åé¡ã¹ããŒãã¡ã³ããèªç±ã«ç·šéããŠãã ããã ãŸãããã¶ã€ã³ããã¥ã¡ã³ããèªç±ã«äœæããŠãã ããïŒ //flutter.dev/docs/resources/design-docsäžç·ã«ç¹°ãè¿ãããšãã§ããŸãïŒããã§ãã @ Hixieã瀺åããŠããããã«ãä»ã®ãšãããåé¡ã¹ããŒãã¡ã³ãã®å¯èœãªéã
ç§ã¯ãã®åé¡ãäœåºŠãèŠçŽããŸããã æ£çŽãªãšããã誀解ãã©ãããæ¥ãŠããã®ãããããªãã®ã§ãäœãæ¹åããã°ããã®ãããããŸããã
å
ã®ã³ã¡ã³ãã¯ãåå©çšæ§/å æ°å解ã®èŠæã«ã€ããŠç¹°ãè¿ãèšåããŠããŸãã ãã€ã©ãŒãã¬ãŒãã«ã€ããŠã®èšåã¯ãããã©ãã¿ãŒã¯åé·ã§ããã§ã¯ãªãããäžéšã®ããžãã¯ã¯åå©çšã§ããŸãããã§ãã
ãã¶ã€ã³ããã¥ã¡ã³ãã®ææ¡ã¯å
¬å¹³ã§ã¯ãªããšæããŸãã ãã®ãããªææžãæžãã®ã«ã¯ããªãã®æéãããããŸãããããŠç§ã¯ç§ã®èªç±ãªæéã«ãããããŠããŸãã
ç§ã¯å人çã«ããã¯ã«æºè¶³ããŠããŸãã ç§ã¯ãããã®åé¡ãèªåã®å©çã®ããã«äœæããŠããã®ã§ã¯ãªããããªãã®æ°ã®äººã
ã«åœ±é¿ãäžããåé¡ã«ã€ããŠã®èªèãé«ããããã§ãã
æ°é±éåãç§ã¯æ¢åã®Flutterã¢ããªã®ã¢ãŒããã¯ãã£ã«ã€ããŠè©±ãåãããã«éãããŸããã 圌ãã¯ããããããã§èšåãããŠãããã®ãšãŸã£ããåãã§ããïŒ
stream
ã€ã³ã¹ã¿ã³ã¹ãå€æŽãããã·ããªãªãåŠçããŸããã§ãã
- äžéšã®ãŠã£ãžã§ããã衚瀺ããããšãã«ãã¡ãã»ãŒãžããæ¢èªãšããŠããŒã¯ãã
ããã¯ãèªåã®ã¢ããªã®1ã€ã§çºçããåé¡ã«äŒŒãŠãããããèå³æ·±ãã±ãŒã¹ã§ããããã§ãã³ãŒããã©ã®ããã«å®è£ ãããã調ã¹ãŸãããããã®ãã°ã§èª¬æãããŠããåé¡ã¯ããŸãèŠãããŸãããç§ãåé¡ãç解ããã®ã«èŠåŽããŠããçç±ã§ãã ããã¯åé¡ã®ã³ãŒãã§ãïŒ
https://github.com/jocosocial/rainbowmonkey/blob/master/lib/src/views/forums.dart
åé¡ãå®éã«çºçããŠããããšã確èªããããã«èª¿æ»ã§ããå®éã®ã¢ããªã®äŸã¯ãããŸããïŒ
ïŒãšããã§ãäžè¬çã«ãã¹ããªãŒã ããŸã£ãã䜿çšããªãããšã匷ããå§ãããŸããäžè¬çã«ãã¹ããªãŒã ã¯äºæ ãæªåããããšæããŸããïŒ
ïŒãšããã§ãäžè¬çã«ãã¹ããªãŒã ããŸã£ãã䜿çšããªãããšã匷ããå§ãããŸããäžè¬çã«ãã¹ããªãŒã ã¯äºæ ãæªåããããšæããŸããïŒ
ïŒç§ã¯å¿ããåæããŸããããããã³ãã¥ããã£ã¯çŸåšå察ã®åå¿ã瀺ããŠããŸããFlutterããChangeNotifier / Listenable / ValueNotifierãå ¬åŒããã±ãŒãžã«æœåºãããšåœ¹ç«ã€ãããããŸããïŒ
åé¡ãå®éã«çºçããŠããããšã確èªããããã«èª¿æ»ã§ããå®éã®ã¢ããªã®äŸã¯ãããŸããïŒ
æ®å¿µãªããéããŸãã ç§ã¯ä»ã®äººãå©ããŠããéã«ç§ãçµéšããããšãå ±æããããšãã§ããã ãã§ãã æå ã«ã¢ããªããããŸããã
ããã¯ãèªåã®ã¢ããªã®1ã€ã§çºçããåé¡ã«äŒŒãŠãããããèå³æ·±ãã±ãŒã¹ã§ããããã§ãã³ãŒããã©ã®ããã«å®è£ ãããã調ã¹ãŸãããããã®ãã°ã§èª¬æãããŠããåé¡ã¯ããŸãèŠãããŸãããç§ãåé¡ãç解ããã®ã«èŠåŽããŠããçç±ã§ãã ããã¯åé¡ã®ã³ãŒãã§ãïŒ
å®è£
ã§ã¯ãããžãã¯ã¯ã©ã€ããµã€ã¯ã«ã«é¢é£ä»ããããŠãããã_build_å
ã«é
眮ãããŠãããããåé¡ãåé¿ããããšãã§ããŸãã
ãã®ç¹å®ã®å Žåã«ã¯æå³ããããããããŸããã ãã®äŸãè¯ãã£ããã©ããã¯ããããŸããã
ããè¯ãäŸã¯ããã«ããŒãªãã¬ãã·ã¥ã§ãã
å žåçãªãã«ãã¥ãªãã¬ãã·ã¥ã§ã¯ã次ã®ããšãå¿ èŠã«ãªããŸãã
ãããŠããã¹ãŠã®ãªãœãŒã¹ãšè€æ°ã®ç»é¢ã«ãã®ãããªæ©èœãå®è£ ããããšæããŸãã ããã«ãç»é¢ã«ãã£ãŠã¯ãäžåºŠã«è€æ°ã®ãªãœãŒã¹ãæŽæ°ãããå ŽåããããŸãã
ChangeNotifier + provider
+ StatefulWidgetã¯ããã®ããžãã¯ãå æ°å解ããã®ã«éåžžã«å€ãã®å°é£ã䌎ããŸãã
ç§ã®ææ°ã®å®éšïŒäžå€æ§ã«åºã¥ããŠããã flutter_hooks
äŸåããŠããŸãïŒã¯ãç®±ããåºããŠããã«ã¹ãã¯ãã«å
šäœããµããŒãããŸãã
final productsProvider = FutureProvider<List<Product>>.autoDispose((ref) async {
final cancelToken = CancelToken();
ref.onDispose(cancelToken.cancel);
return await repository.fetchProducts(cancelToken: cancelToken);
});
// ...
Widget build(context) {
// Listens to the Future created by productsProvider and handles all the refresh logic
AsyncValue<List<Product>> products = useRefreshProvider(
productsProvider,
// TODO consider making a custom hook to encaplusate the snackbar logic
onErrorAfterRefresh: (err, stack) => Scaffold.of(context).showSnackBar(...),
);
return RefreshIndicator(
onRefresh: () => context.refresh(productsProvider),
child: products.when(
loading: () {
return const SingleChildScrollView(
physics: AlwaysScrollableScrollPhysics(),
child: CircularProgressIndicator(),
);
},
error: (err, stack) {
return SingleChildScrollView(
physics: const AlwaysScrollableScrollPhysics(),
child: Text('Oops, something unexpected happened\n$err'),
);
},
data: (products) {
return ListView.builder(
itemCount: products.length,
itemBuilder: (context, index) {
return ProductItem(products[index]);
},
);
},
),
);
}
ãã®ããžãã¯ã¯å®å šã«èªå·±å®çµåã§ãã ããã¯ãä»»æã®ç»é¢å ã®ä»»æã®ãªãœãŒã¹ã§åå©çšã§ããŸãã
ãŸãã1ã€ã®ç»é¢ã§è€æ°ã®ãªãœãŒã¹ãäžåºŠã«æŽæ°ãããå Žåã¯ã次ã®ããšãã§ããŸãã
AsyncValue<First> first = useRefreshProvider(
firstProvider,
onErrorAfterRefresh: ...
);
AsyncValue<Second> second = useRefreshProvider(
secondProvider,
onErrorAfterRefresh: ...
);
return RefreshIndicator(
onRefresh: () {
return Future.wait([context.refesh(firstProvider), context.refresh(secondProvider)]);
}
...
)
ãã®ããžãã¯ããã¹ãŠãŠã£ãžã§ããã®å€ã®ã¢ããªã®ç¶æ ã«ããã¢ããªã®ç¶æ ã«çŸåšã®ã¢ããªã®ç¶æ ãåæ ãããããšããå§ãããŸãã ãã«ããŠæŽæ°ããå ŽåããŠã£ãžã§ããå ã«ç¶æ ã¯å¿ èŠãããŸãããæŽæ°ãä¿çäžã§ããããšãåšå²ã®ç¶æ ã«éç¥ãããã®å°æ¥ãå®äºããã®ãåŸ ã€ã ãã§ãã
ãšã©ãŒãšããŒããšããŒã¿ã®ã¬ã³ããªã³ã°æ¹æ³ã決å®ããã®ã¯ãåšå²ã®ç¶æ ã®è²¬ä»»ã§ã¯ãããŸããã
ãã®ããžãã¯ãã¢ã³ããšã³ãç¶æ
ã«ããŠããUIãããã¹ãŠã®ããžãã¯ãåé€ãããããã§ã¯ãããŸããã
UIã¯ããšã©ãŒãå
šç»é¢è¡šç€ºã«ãããã¹ããã¯ããŒã«è¡šç€ºãããã決å®ããå¿
èŠããããŸãã
ããã§ããããŒãžããªããŒãããããšãã«ãšã©ãŒã匷å¶çã«æŽæ°ããå¿
èŠããããŸã
ãããŠãããã¯åå©çšæ§ãäœããªããŸãã
ã¬ã³ããªã³ã°ããžãã¯ãåšå²ã®ç¶æ
ã§ã¯ãªããŠã£ãžã§ããã§å®å
šã«å®çŸ©ãããŠããå Žåãããã¯_any_Futureã§æ©èœããŸã
ç§ã¯ããªããããªãã®æåŸã®ã³ã¡ã³ãã§äœã䞻匵ããŠããã®ãæ¬åœã«ç解ããŠããŸããã ç§ã®ãã€ã³ãã¯ãåã«åŒçšããã³ãŒãã§ç€ºãããŠããããã«ãäžèšã®æŽæ°ã€ã³ãžã±ãŒã¿ãŒã³ãŒãã®ããã«åçŽãªããšãè¡ãããã«ãã¬ãŒã ã¯ãŒã¯ãå€æŽããå¿ èŠããªããšããããšã§ãã
æŽæ°ã€ã³ãžã±ãŒã¿ãŒã ãã§ãªããã¢ãã¡ãŒã·ã§ã³ãªã©ã®ãããã®ã¿ã€ãã®ã€ã³ã¿ã©ã¯ã·ã§ã³ãå€æ°ããå Žåã¯ãã¢ããªã®ç¶æ ã«ããããããå¿ èŠã«æãè¿ãå Žæã«ã«ãã»ã«åããæ¹ãããã§ããããã¢ããªã®ç¶æ ã ããã§ããã¢ããªå ã®è€æ°ã®å Žæã§å¿ èŠãªãå Žåã¯ãã¢ããªå ã®ãã¹ãŠã®ã€ã³ã¿ã©ã¯ã·ã§ã³ã®è©³çŽ°ãç¥ãå¿ èŠã¯ãããŸããã
æ©èœã®è€éããšãã®åå©çšæ§ã«ã€ããŠã¯åæããŠããªããšæããŸãã
ãã®ãããªæ©èœãç°¡åã§ããããšã瀺ãäŸã¯ãããŸããïŒ
äžã§æžãã1ã€ã®ã¢ããªã®ãœãŒã¹ã«ãªã³ã¯ããŸããã ããã¯ç¢ºãã«å®ç§ãªã³ãŒãã§ã¯ãªãã次ã®ãªãªãŒã¹ã®ããã«ãã®äžéšãæžãçŽãäºå®ã§ããããã®å·ã§èª¬æããåé¡ã¯çºçããŸããã§ããã
ããããããªãã¯Flutterã®æè¡ãªãŒããŒã®1人ã§ãã
åé¡ã«çŽé¢ããå Žåã§ããããã«è§£æ±ºçãèãåºãã®ã«ååãªã¹ãã«ããããŸãã
ãããäžæ¹ã§ãããªãã®æ°ã®äººã ã次ã®ã³ãŒãã®äœãåé¡ãªã®ããç解ããŠããŸããã
FutureBuilder<User>(
future: fetchUser(),
builder: ...,
)
ãã®äºå®ã¯ãStackOverflowã§Q / AIãã©ãã»ã©äººæ°ãââãããã«ãã£ãŠèšŒæãããŠããŸãã
åé¡ã¯ãåå©çšå¯èœã§å
ç¢ãªæ¹æ³ã§ç¶æ
ããžãã¯ãæœè±¡åããããšãäžå¯èœã§ãããšããããšã§ã¯ãããŸããïŒããã§ãªããã°ããã®åé¡ãäœæããŠãæå³ããããŸããïŒã
åé¡ã¯ãããããã®ã«æéãšçµéšã®äž¡æ¹ãå¿
èŠãªããšã§ãã
å
¬åŒã®ãœãªã¥ãŒã·ã§ã³ãæäŸããããšã§ãã¢ããªã±ãŒã·ã§ã³ãä¿å®äžèœã«ãªãå¯èœæ§ãäœããªããå
šäœçãªçç£æ§ãšéçºè
ã®ãšã¯ã¹ããªãšã³ã¹ãåäžããŸãã
誰ããããªãã®ç©ä»¶ã®ææ¡ãæãä»ãããšãã§ããããã§ã¯ãããŸããã ãã®ãããªãã®ãFlutterå
ã«æ§ç¯ãããå Žåãããã¯ææžåãããå¯èŠæ§ãç²åŸããæçµçã«ã¯æåããèããããšã®ãªã人ã
ãæ¯æŽããŸãã
åé¡ã¯ãã¢ããªãäœã§ããããç¶æ ãã©ã®ããã«èŠããããªã©ã«å®éã«äŸåããããšã§ãã ããã§ã®è³ªåããã¢ããªã®ç¶æ ãã©ã®ããã«ç®¡çããããã§ããå Žåãçãã¯ããã¯ã®ãããªãã®ã§ã¯ãããŸããããããè¡ãããã®ããŸããŸãªæ¹æ³ã«ã€ããŠèª¬æããããŸããŸãªç¶æ³ã«å¿ããŠããŸããŸãªææ³ãæšå¥šããå€ãã®ããã¥ã¡ã³ãã§ã...åºæ¬çã«ããã®äžé£ã®ããã¥ã¡ã³ãïŒ https ïŒ
äžæçãªç¶æ ãšã¢ããªã®ç¶æ ããããŸãããå¥ã®ãŠãŒã¹ã±ãŒã¹ãããããã§ããåäžã®ã¿ã€ãã®ãŠã£ãžã§ããã®ã¿ã«é¢ä¿ããããããã§ããã®ã¿ã€ãã®ãŠã£ãžã§ããéã§å ±æãããç¶æ ã§ãã
ããšãã°ã ScrollController
ã¯ããçš®ã®ã¢ãã¡ãŒã·ã§ã³ãåŒã³åºãå ŽåããããŸããããããã°ããŒãã«ã¢ããªã®ç¶æ
ã«ããããšã¯å¿
ãããé©åã§ã¯ãããŸãããããã¯ãã¢ããªå
šäœã§äœ¿çšããå¿
èŠã®ããããŒã¿ã§ã¯ãªãããã§ãã ãã ããè€æ°ã®ScrollController
ãåãããžãã¯ãæã£ãŠããå¯èœæ§ããããããããã®éã§ãã®ã©ã€ããµã€ã¯ã«ããžãã¯ãå
±æããå¿
èŠããããŸãã ç¶æ
ã¯ãŸã ScrollController
ã ããªã®ã§ãã°ããŒãã«ã¢ããªã®ç¶æ
ã§ã¯ãããŸããããããžãã¯ãã³ããŒããŠè²Œãä»ãããšãšã©ãŒãçºçãããããªããŸãã
ããã«ããã®ããžãã¯ãããã±ãŒãžåããŠãå°æ¥ã®ãããžã§ã¯ãã ãã§ãªããä»ã®ãããžã§ã¯ãã§ãããæ§æããããããããšãã§ããŸãã ãµã€ãuseHooksãèŠããšãç¹å®ã®äžè¬çãªã¢ã¯ã·ã§ã³ãåºååããããžãã¯ã®å€ãã®éšåãããããŸãã useAuth
ã䜿çšããå Žåã¯ãäžåºŠæžã蟌ãã ãã§ã initState
ãŸãã¯dispose
åŒã³åºããéãããã©ããããŸãã¯éåæé¢æ°ã«then
ããããã©ãããå¿é
ããå¿
èŠã¯ãããŸããã catch
ã é¢æ°ã¯äžåºŠã ãæžãããã®ã§ããšã©ãŒã®äœå°ã¯åºæ¬çã«ãªããªããŸãã ãããã£ãŠããã®çš®ã®ãœãªã¥ãŒã·ã§ã³ã¯ãåãã¢ããªã®è€æ°ã®éšåãè€æ°ã®ã¢ããªéã§ããæ§æããããã ãã§ãªãããšã³ãããã°ã©ããŒã«ãšã£ãŠãå®å
šã§ãã
ç§ã¯ããã¯ã䜿çšããŠãã人ã ã«ç°è°ã¯ãããŸããã ç§ã®ç¥ãéããããã劚ãããã®ã¯äœããããŸããã ïŒäœããããã劚ããŠããå Žåã¯ãããã«ã€ããŠãã°ãå ±åããŠãã ãããïŒ
ãã®ãã°ã¯ããã¯ã«é¢ãããã®ã§ã¯ãªãããç¶æ ããžãã¯ã®åå©çšã¯åé·/å°é£ããããã«é¢ãããã®ã§ããããããFlutterãžã®å€æŽãå¿ èŠãšããçç±ãç解ããã®ã«ãŸã èŠåŽããŠããŸãã ã¢ããªã±ãŒã·ã§ã³ãäœããã®æ¹æ³ã§æ§é åããããšã§åé·æ§ãåé¿ããæ¹æ³ã瀺ãå€ãã®äŸïŒããã¯ãå«ãïŒããããããã«é¢ããããã¥ã¡ã³ãã¯ãã§ã«ãããããããŸãã
ãªãã»ã©ãFlutterãå€æŽããã«ãã«ããããããã¯ããã±ãŒãžã®ãããªãã®ãååšããå Žåãããã¯ã®ãã¡ãŒã¹ãããŒãã£ãœãªã¥ãŒã·ã§ã³ãå¿ èŠãªã®ã¯ãªãã§ããïŒ @rrousselGitã¯ããã«ããããçããããšãã§ãããš
è¡šé¢äžã¯flutter_hooksããã±ãŒãžããã§ã«ååšãããããããã«å ããŠãããã¯ããµããŒãããããã«Flutterã«åºæ¬çãªå€æŽãå ããå¿ èŠãããçç±ãæ··ä¹±ããŠããŸãã
Flutterã«å€æŽãå¿ èŠãªçç±ãç解ããã®ã«ãŸã èŠåŽããŠããŸãã
ã³ãã¥ããã£ãããã±ãŒãžãäœæããããã«ãã®åé¡ã解決ãããšèšãããšã¯ãç§ãFreezedãäœæãããããDartã¯ããŒã¿ã¯ã©ã¹ãšå
±çšäœåãå¿
èŠãšããªããšèšã£ãŠãããããªãã®
Freezedã¯ããããã®åé¡ã®äž¡æ¹ã®è§£æ±ºçãšããŠã³ãã¥ããã£ã«éåžžã«å¥œãŸããŠãããããããŸããããããã§ãç§ãã¡ã¯ãã£ãšããŸãããããšãã§ããŸãã
FlutterããŒã ã¯ãã³ãã¥ããã£ããããŸã§ä»¥äžã«æŽ»ââçšããŠããŸãã ã¹ã¿ãã¯å šäœãå€æŽããäž¡æ¹ã®æ©èœããããŸãã åã ã®éšåã®å°é家ã§ãã人ã ã ãããŠå¿ èŠãªä»äºãåŸæŽããããã®çµŠæã
ãã®åé¡ã«ã¯ãããå¿
èŠã§ãã
泚æïŒReactããŒã ã®ç®æšã®1ã€ã¯ãJSXã®ããã«ãããã¯ãèšèªã®äžéšã«ããããšã§ãã
èšèªã®ãµããŒãããªããŠããã¢ãã©ã€ã¶ãŒã§ã®äœæ¥ãå¿ èŠã§ãã ããŒãããã; flutter / devtools; ãŸããFlutterãè¡ãããŸããŸãªããšãã¹ãŠãåçŽåããããã®å€ãã®ããã¯ïŒæé»ã®ã¢ãã¡ãŒã·ã§ã³ããã©ãŒã ãªã©ïŒã
Flutterã®äžè¬çãªå²åŠã¯å°ããªã³ã¢ãæã£ãŠãããšã¯ãããããã¯è¯ãè°è«ã ãšç§ã¯åæããŸãã ãã®ãããGoogleããã®ãã®ã§ãã£ãŠããããã±ãŒãžãšããŠæ°ããæ©èœãè¿œå ããããšãå¢ããŠããŸããæåãã¢ãã¡ãŒã·ã§ã³ãåç §ããŠãã ããã ããã«ãããæéã®çµéãšãšãã«åŠç¿ããã³å€æŽããããã®æè»æ§ãé«ãŸããŸãã ããã±ãŒãžãäžååã§ãããšãã説åŸåã®ããæè¡çãªçç±ããªãéãããã®ã¹ããŒã¹ã«ã€ããŠãåãããšãè¡ããŸãïŒãããŠãæ¡åŒµã¡ãœããã䜿çšãããšããããŸã§ä»¥äžã«å¯èœæ§ãäœããªããŸãïŒã
Flutterã®ã³ã¢ã«ç©äºãå ¥ããã®ã¯é£ããã§ãã çŽæ¥ã®çµéšããããç¥ã£ãŠããããã«ã1ã€ã®èª²é¡ã¯ããªã¢ã¯ãã£ãUIã¢ãŒããã¯ãã£ã§äœãããŸãæ©èœãããã«ã€ããŠç§ãã¡å šå¡ãåŠã¶ã«ã€ããŠãç¶æ ãé²åããŠããé åã§ãããšããããšã§ãã 2幎åãåè ãéžã¶ããšãäœåãªããããå Žåã¯ãBLoCãéžæããå¯èœæ§ããããŸããããã¡ããããããã€ããŒããã±ãŒãžãåŒãç¶ãããçŸåšã¯ããã©ã«ãã®æšå¥šäºé ã§ãã
ç§ã¯ãflutter_hooksãŸãã¯çœåŒåã®ããåæ§ã®ããã¯ããã±ãŒãžããµããŒãããGoogleæ¡çšã®è²¢ç®è ãå¿«é©ã«æ³åããããšãã§ããŸããïŒãã¡ãããç§ãã¡ã®æ³šæã奪ãåãä»ã®ä»äºã¯
èå³æ·±ãè°è«ã@ timsneathã Rustã³ãã¥ããã£ãåæ§ã®ããšãè¡ããŸããèšèªãŸãã¯ãã¬ãŒã ã¯ãŒã¯ã®ã³ã¢ã©ã€ãã©ãªãŸãã¯æšæºã©ã€ãã©ãªã«å°å ¥ããããšããããåãåºãã®ãéåžžã«é£ããããã§ãã Rustã®å Žåãäžäœäºææ§ãæ°žä¹ ã«ç¶æãããã®ã§äžå¯èœã§ãã ãããã£ãŠã圌ãã¯ããã±ãŒãžãå°çãããŸã§åŸ ã¡ãå°æ°ã®åè ã ããçŸãããŸã§äºãã«ç«¶äºãããããããããèšèªã«æãç³ã¿ãŸãã
ããã¯ãFlutterã®å Žåãšåæ§ã®ã±ãŒã¹ã§ããå¯èœæ§ããããŸãã Reactãã¯ã©ã¹ããããã¯ã«ç§»åããªããã°ãªããªãã£ãããããã§ãã¯ã©ã¹ãç¶æããªããã°ãªããã人ã ã移è¡ããªããã°ãªããªãã£ãããã«ãåŸã§ããã¯ãããè¯ããã®ããããããããŸããã ãã®å Žåãã³ã¢ã«è¿œå ããåã«ã競åããç¶æ 管çãœãªã¥ãŒã·ã§ã³ãçšæããæ¹ãããå ŽåããããŸãã ãããŠãããããç§ãã¡ã³ãã¥ããã£ã¯ãããã¯ã®äžã§é©æ°ããããããã«è¯ã解決çãèŠã€ããããšããå¿ èŠããããŸãã
ç§ã¯ãã®æžå¿µãç解ããŠããŸãããããã¯ç¶æ 管çãœãªã¥ãŒã·ã§ã³ã«é¢ãããã®ã§ã¯ãããŸããã
ãã®ãããªæ©èœã¯ãAttachedwidgetãšStatefulWidgetã«è¿ããã®ã§ãã ããã¯äœã¬ãã«ã®ããªããã£ãã§ãããèšèªæ©èœãšåããããäœããªãå¯èœæ§ããããŸãã
ããã¯ã¯ãã¬ãŒã ã¯ãŒã¯ããç¬ç«ããŠãããããããŸããããããã¯éã«ãã£ãŠã®ã¿ã§ãã
åã«è¿°ã¹ãããã«ããã®åé¡ãžã®å¥ã®ãã¹ã¯æ¬¡ã®ããã«ãªããŸãã
context.onDispose(() {
});
ãããŠåæ§ã®ã€ãã³ããªã¹ããŒã
ããããããããã¬ãŒã ã¯ãŒã¯ããå®è£
ããããšã¯äžå¯èœã§ãã
ããŒã ãäœãæãã€ãã®ãããããŸããã
ãããããã®ãããªãœãªã¥ãŒã·ã§ã³ãElementã®ããé£ã«ãªããã°ãªããªãå¯èœæ§ãæé€ããããšã¯ã§ããŸãã
æ¡åŒµæ©èœã¯ãããå©ããŸããïŒ
ïŒãã ããå¥ã®åé¡ã§ããã«ã€ããŠè©±ãå¿
èŠããããããããŸãããããã§ã¯ãããã¯ããå€ããŠããŸãã人ã
ãç®ã«ããŠããåé¡ããšã«1ã€ã®åé¡ãããã°ãé©åãªå Žæã§è§£æ±ºçã«ã€ããŠè©±ãåãããšãã§ããã°ãšæããŸããããã§ã¯ãããŸããã context.onDispose
ãåé·æ§ã«ã©ã®ããã«åœ¹ç«ã€ããæ確ã«ããŸããïŒ
ããã«é¢é£ããŠç§ãã¡ãæãã€ãããšãã§ããããã€ãã®æ¬åœã«è¯ãèšèªã®ææ¡ããããšåŒ·ãæããŸãã
ããããç¹å®ã®ç¶æ 管çã€ãã£ãªã ãã©ã®ããã«å¯èœã«ããããããããããã«ã€ããŠããå ·äœçã«è©±ãããšã圹ç«ã€ãšæããŸãã 次ã«ãããããäœãå¯èœã«ããã©ã®ãããªãã¬ãŒããªãã䌎ãå¯èœæ§ãããããããçå£ã«æ€èšããããšãã§ããŸãã
ç¹ã«ãVMã©ã³ã¿ã€ã ãšJSã©ã³ã¿ã€ã ã®äž¡æ¹ã§ã©ã®ããã«æ©èœããããæ€èšããããšãã§ããŸãã
context.onDispose
ãåé·æ§ã«ã©ã®ããã«åœ¹ç«ã€ãã¯æ確ã§ã¯ãããŸãããïŒ
åã«è¿°ã¹ãããã«ããã®åé¡ã¯åé·æ§ãããã³ãŒãã®åå©çšæ§ã«é¢ãããã®ã§ãã ããããããå€ãã®ã³ãŒããåå©çšã§ããå Žåãããã¯æé»çã«åé·æ§ãæžããã¯ãã§ãã
context.onDispose
ããã®åé¡ã«é¢é£ããæ¹æ³ã¯ãçŸåšã®æ§æã§ã¯æ¬¡ã®ãšããã§ãã
AnimationController controller;
<strong i="11">@override</strong>
void initState() {
controller = AnimationController(...);
}
<strong i="12">@override</strong>
void dispose() {
controller.dispose();
}
åé¡ã¯ïŒ
context.onDispose
ã次ã®ããšãã§ããŸãã
<strong i="21">@override</strong>
void initState() {
controller = AnimationController(...);
context.onDispose(controller.dispose);
}
èå³æ·±ãéšåã¯æ¬¡ã®ãšããã§ãã
@ãªãŒããŒã©ã€ã
void initStateïŒïŒ{
ã³ã³ãããŒã©ãŒ= someReusableLogicïŒcontextïŒ;
}
`` `
controller
ã®ããžãã¯ã¯ç°¡åã«èªã¿åãããšãã§ããŸãããã®ã¢ãããŒãã®åé¡ã¯æ¬¡ã®ãšããã§ãã
context.myLifecycle(() {...})
ã¯ããããªããŒãã§ããŸããsomeReusableLogic
ã«StatefulWidget
ããããããã£ãèªã¿åãããæ¹æ³ã¯äžæã§ããAnimationController
ã®Duration
ãŠã£ãžã§ããã®ãã©ã¡ãŒã¿ãšããŠæž¡ãããšãã§ããŸãã ãããã£ãŠãæéãå€åããã·ããªãªãåŠçããå¿
èŠããããŸããValueNotifier
ã«é Œã£ããããªã¹ããŒãåŠçãããããã«ãæéã®çµéãšãšãã«å€åããå¯èœæ§ã®ãããªããžã§ã¯ããè¿ãé¢æ°ãå®è£
ããæ¹æ³ã¯äžæã§ããèšèªã®ææ¡ã«ã€ããŠèããŸãã ç§ã«ã¯ããã€ãã®ã¢ã€ãã¢ããããŸãããä»è©±ã䟡å€ã®ãããã®ã¯äœããããŸããã
åã«è¿°ã¹ãããã«ããã®åé¡ã¯åé·æ§ãããã³ãŒãã®åå©çšæ§ã«é¢ãããã®ã§ã
Okã ããã«ã€ããŠå ·äœçã«èª¬æããŠããæ°ãããã°ãæåºããŠããã ããŸãããïŒ ãã®ãã°ã¯ãæåéããç¶æ ããžãã¯ã®åå©çšã¯åé·/å°é£ãããããšåŒã°ããŸãã åé·æ§ãåé¡ã§ã¯ãªãå Žåã_this_ã¯åé¡ã§ã¯ãããŸããã
context.onDispose
ã次ã®ããšãã§ããŸãã<strong i="11">@override</strong> void initState() { controller = AnimationController(...); context.onDispose(controller.dispose); }
context
ãããã«é¢é£ããçç±ãããããŸããïŒãããŠonDispose
ã¯åœåèŠåã«éåããŠããŸãïŒã ãã ããç Žæ£äžã«å®è¡ãããã®ãç»é²ããæ¹æ³ãå¿
èŠãªå Žåã¯ãä»æ¥ãããç°¡åã«è¡ãããšãã§ããŸãã
mixin StateHelper<T extends StatefulWidget> on State<T> {
List<VoidCallback> _disposeQueue;
void queueDispose(VoidCallback callback) {
_disposeQueue ??= <VoidCallback>[];
_disposeQueue.add(callback);
}
<strong i="17">@override</strong>
void dispose() {
if (_disposeQueue != null) {
for (VoidCallback callback in _disposeQueue)
callback();
}
super.dispose();
}
}
ãã®ããã«åŒãã§ãã ããïŒ
class _MyHomePageState extends State<MyHomePage> with StateHelper<MyHomePage> {
TextEditingController controller;
<strong i="21">@override</strong>
void initState() {
super.initState();
controller = TextEditingController(text: 'button');
queueDispose(controller.dispose);
}
...
AnimationController someReusableLogic(BuildContext context) { final controller = AnimationController(...); controller.onDispose(controller.dispose); controller.forward(); void listener() {} controller.addListener(listener); context.onDispose(() => controller.removeListener(listener)); } ... <strong i="25">@override</strong> void initState() { controller = someReusableLogic(context); }
ããªãããããè¡ãããšãã§ããŸãïŒ
AnimationController someReusableLogic<T extends StatefulWidget>(StateHelper<T> state) {
final controller = AnimationController(...);
state.queueDispose(controller.dispose);
controller.forward();
void listener() {}
controller.addListener(listener);
state.queueDispose(() => controller.removeListener(listener));
return controller;
}
...
<strong i="6">@override</strong>
void initState() {
controller = someReusableLogic(this);
}
ãã®ã¢ãããŒãã®åé¡ã¯æ¬¡ã®ãšããã§ãã
context.myLifecycle(() {...})
ã¯ããããªããŒãã§ããŸãã
ãã®ã³ã³ããã¹ãã§ã¯ãinitStateã§åŒã³åºããããã®ã ãã®ããã§ãããããåé¡ã§ã¯ãªãããã§ãã ç§ã¯äœãã足ããªãã®ã§ããïŒ
- é¢æ°ããŠã£ãžã§ããå®çŸ©ã«ç·å¯ã«çµåããã«ã
someReusableLogic
ã«StatefulWidget
ããããããã£ãèªã¿åãããæ¹æ³ã¯äžæã§ãã
ããšãã°ãAnimationController
ã®Duration
ãŠã£ãžã§ããã®ãã©ã¡ãŒã¿ãšããŠæž¡ãããšãã§ããŸãã ãããã£ãŠãæéãå€åããã·ããªãªãåŠçããå¿ èŠããããŸãã
disposeãã¥ãŒãšåãããã«ãdidChangeWidgetãã¥ãŒãè¿œå ããã®ã¯éåžžã«ç°¡åã§ãã
mixin StateHelper<T extends StatefulWidget> on State<T> {
List<VoidCallback> _disposeQueue;
List<VoidCallback> _didUpdateWidgetQueue;
void queueDispose(VoidCallback callback) {
_disposeQueue ??= <VoidCallback>[];
_disposeQueue.add(callback);
}
void queueDidUpdateWidget(VoidCallback callback) {
_didUpdateWidgetQueue ??= <VoidCallback>[];
_didUpdateWidgetQueue.add(callback);
}
<strong i="24">@override</strong>
void didUpdateWidget(T oldWidget) {
super.didUpdateWidget(oldWidget);
if (_didUpdateWidgetQueue != null) {
for (VoidCallback callback in _didUpdateWidgetQueue)
callback();
}
}
<strong i="25">@override</strong>
void dispose() {
if (_disposeQueue != null) {
for (VoidCallback callback in _disposeQueue)
callback();
}
super.dispose();
}
}
AnimationController conditionalAnimator(StateHelper state, ValueGetter<bool> isAnimating, VoidCallback listener) {
final controller = AnimationController(vsync: state as TickerProvider, duration: const Duration(seconds: 1));
state.queueDispose(controller.dispose);
controller.addListener(listener);
state.queueDispose(() => controller.removeListener(listener));
if (isAnimating())
controller.repeat();
state.queueDidUpdateWidget(() {
if (isAnimating()) {
controller.repeat();
} else {
controller.stop();
}
});
return controller;
}
ãã®ããã«äœ¿çšãããŸãïŒ
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
<strong i="6">@override</strong>
Widget build(BuildContext context) {
return MaterialApp(
home: MyHomePage(animating: false),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.animating}) : super(key: key);
final bool animating;
<strong i="7">@override</strong>
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with StateHelper<MyHomePage>, SingleTickerProviderStateMixin {
AnimationController controller;
<strong i="8">@override</strong>
void initState() {
super.initState();
controller = conditionalAnimator(this, () => widget.animating, () { print(controller.value); });
}
<strong i="9">@override</strong>
Widget build(BuildContext context) {
return Center(
child: FadeTransition(
opacity: controller,
child: Text('Hello', style: TextStyle(fontSize: 100.0, color: Colors.white)),
),
);
}
}
ValueNotifier
ã«é Œã£ããããªã¹ããŒãåŠçãããããã«ãæéã®çµéãšãšãã«å€åããå¯èœæ§ã®ãããªããžã§ã¯ããè¿ãé¢æ°ãå®è£ ããæ¹æ³ã¯äžæã§ãã
- ããã¯ãèšç®ãããç¶æ ã«ãšã£ãŠç¹ã«éèŠã§ãã
ãããããã§äœãæå³ããã®ãããããªããValueNotifierãããšãã°ValueListenableBuilderã®äœãåé¡ã«ãªã£ãŠããŸããïŒ
åã«è¿°ã¹ãããã«ããã®åé¡ã¯åé·æ§ãããã³ãŒãã®åå©çšæ§ã«é¢ãããã®ã§ã
Okã ããã«ã€ããŠå ·äœçã«èª¬æããŠããæ°ãããã°ãæåºããŠããã ããŸãããïŒ ãã®ãã°ã¯ãæåéããç¶æ ããžãã¯ã®åå©çšã¯åé·/å°é£ãããããšåŒã°ããŸãã åé·æ§ãåé¡ã§ã¯ãªãå Žåãããã¯åé¡ã§ã¯ãããŸããã
ç§ã¯ãã®è°è«ã«ããªãäžå¿«ã«ãªãå§ããŠããŸãã ç§ã¯ãã§ã«ãã®ç¹ã«åã«çããŸããïŒ
ãã®åé¡ã®ãããã¯ã¯åå©çšæ§ã§ãããåé·æ§ã¯åå©çšæ§ã®åé¡ã®çµæãšããŠè°è«ãããŸãã äž»èŠãªãããã¯ãšããŠã§ã¯ãããŸããã
äžéšã®ã³ã¡ã³ãã«ã¯ãåé·æ§ã«ã€ããŠèšåããŠããç®æ¡æžãã1ã€ã ããããŸããããã¯ãäž»ã«2ã€ã®ã¬ãã«ã®ã€ã³ãã³ãã察象ãšããStreamBuilderã®å Žåã§ãã
ãªãã³ã³ããã¹ããããã«é¢é£ããã®ãããããŸãã[...]ã ãã ããç Žæ£äžã«å®è¡ãããã®ãç»é²ããæ¹æ³ãå¿ èŠãªå Žåã¯ãä»æ¥ãããç°¡åã«è¡ãããšãã§ããŸãã
context.onDispose
ç«ã¡äžãããšããç§ã¯ãããè¯ã解決çã§ã¯ãªããšã¯ã£ããèšã£ãã
ãããè°è«ãšã©ã®ããã«é¢ä¿ããŠããããå°ããããã®ã§ãç§ã¯ããã説æããŸããã
ãªãã«é¢ããŠã¯context
ã®ä»£ããã«StateHelper
ããã¯ïŒStatelessWidgetã§ã®äœæ¥ã®ããã«ïŒãããæè»æ§ãããã®ã§ãããã¯ãããŸã
context.myLifecycleïŒïŒïŒ{...}ïŒã¯ããããªããŒãå¯èœã§ã¯ãããŸãã
ãã®ã³ã³ããã¹ãã§ã¯ãinitStateã§åŒã³åºããããã®ã ãã®ããã§ãããããåé¡ã§ã¯ãªãããã§ãã ç§ã¯äœãã足ããªãã®ã§ããïŒ
å€æŽãããå¯èœæ§ããããŸãïŒ
initState() {
context.myLifecycle(() => print('hello'));
}
ã®äžãžïŒ
initState() {
context.myLifecycle(() => print('world'));
}
ããã¯ã myLifecycle
ã³ãŒã«ããã¯ãžã®å€æŽãé©çšããŸããã
ãããã䜿çšããå ŽåïŒ
myLifecycle() {
super.myLifecycle();
print('hello');
}
ãã®åŸãããããªããŒããæ©èœããŸãã
ãããããã§äœãæå³ããã®ãããããªããValueNotifierãããšãã°ValueListenableBuilderã®äœãåé¡ã«ãªã£ãŠããŸããïŒ
ãã®æ§æã¯ãBuilderã䜿çšããå¿ èŠããªãããã«èšèšãããŠãããããå ã®åé¡ã«æ»ããŸããã
ããã«ãé¢æ°ãæ¬åœã«æ§æå¯èœã«ãããå Žåã¯ã ValueGetter
+ queueDidUpdateWidget
ææ¡ã§ã¯ãªããé¢æ°ã¯ãã©ã¡ãŒã¿ãŒãšããŠValueNotifier
ãåãå¿
èŠããããŸãã
AnimationController conditionalAnimator(StateHelper state, ValueListenable<bool> isAnimating, VoidCallback listener) {
...
}
ãã®é¢æ°ã䜿çšããŠãããŠã£ãžã§ããã«ãã£ãŠã¯ã didUpdateWidget
以å€ã®å ŽæããisAnimating
ãååŸãããå Žåãããããã§ãã
ããå Žæã§ã¯ãdidUpdateWidgetãããããŸããã å¥ã®äŸã§ã¯ãdidChangeDependenciesã§ããå¯èœæ§ããããŸãã ããã«å¥ã®å Žæã§ã¯ã stream.listen
ã®ã³ãŒã«ããã¯å
ã«ããå¯èœæ§ããããŸãã
ãããããããã®ã·ããªãªãç°¡åã«ValueNotifier
ã«å€æããé¢æ°ã«ãã®ãããªéç¥æ©èœããªãã¹ã³ãããæ¹æ³ãå¿
èŠã§ãã
ã§ããããç§ãã¡ã¯ç§ãã¡ã®ç掻ãèããå°é£ã«ããŠããŸãã
ç§ãæããã®ãã¿ãŒã³ãããã ConditionalAnimatorBuilder
ã䜿çšããæ¹ãçŸå®çã§ç°¡åã§ãã
ãªãã«é¢ããŠã¯
context
ã®ä»£ããã«StateHelper
ããã¯ïŒStatelessWidgetã§ã®äœæ¥ã®ããã«ïŒãããæè»æ§ãããã®ã§ãããã¯ãããŸã
StatelessWidgetã¯ãã¹ããŒãã¬ã¹ãŠã£ãžã§ããçšã§ãã éèŠãªã®ã¯ãç¶æ ãäœæããããç©ãç Žæ£ããããdidUpdateWidgetã«åå¿ãããããªããšããããšã§ãã
ã¯ããããããªããŒãã®ããšã§ãã ãã®ãããinitStateã«ã¯ããŒãžã£ãé 眮ããã®ã§ã¯ãªãã¡ãœããã䜿çšããŸãã
ç³ãèš³ãããŸãããããããèšãç¶ããŠãããã€ã©ã€ã©ããŠããã«éããªãããšã¯ç解ããŠããŸãããããã§è§£æ±ºããããšããŠããåé¡ãäœã§ãããã¯ãŸã ããããŸããã å ã®ãã°ã®èŠçŽãšå ã®èª¬æã®å€§éšåã«ãããšãããã¯åé·ã ãšæããŸããããããã§ã¯ãªãããšãç解ããŠããŸãã ããã§ãåé¡ã¯äœã§ããïŒ ããã«ã¯çžäºã«æä»çãªæ¬²æ±ãããããããããã®ãã°ã®å€ãã®ã³ã¡ã³ãã«åºãã£ãŠããããã§ãã
ç§ãã¡ãããã§é¢ãã£ãŠãããã®å埩çãªãã³ã¹ã¯ãç©äºãæãéããããã®çç£çãªæ¹æ³ã§ã¯ãããŸããã åã«ãèšã£ãããã«ãããã§äœããåŸãããã®æè¯ã®æ¹æ³ã¯ãçŽé¢ããŠããåé¡ãç解ã§ããæ¹æ³ã§èª¬æãããã¹ãŠã®ããŒãºã1ãæã§èª¬æãããŠãŒã¹ã±ãŒã¹ã§èª¬æããããšã§ãã ãœãªã¥ãŒã·ã§ã³ããªã¹ãããªãããšããå§ãããŸããç¹ã«ãããŒãºãæºãããªãããšãããã£ãŠãããœãªã¥ãŒã·ã§ã³ã¯ãªã¹ãããªãããšããå§ãããŸãã ãããã®ãœãªã¥ãŒã·ã§ã³ãäžé©åã«ããå¿ èŠæ§ã説æã«èšèŒãããŠããããšã確èªããŠãã ããã
æ£çŽãªãšãããåºæ¬çã«ã¯ãŸã£ããç°ãªããã¬ãŒã ã¯ãŒã¯èšèšãæ±ããŠããããã«æããŸãã ããã¯ãŸã£ããåé¡ãããŸããããFlutterã§ã¯ãããŸããã å¥ã®ãã¬ãŒã ã¯ãŒã¯ãå®è¡ããå Žåãããã¯å¥ã®ãã¬ãŒã ã¯ãŒã¯ã«ãªããŸããã_this_ãã¬ãŒã ã¯ãŒã¯ã§å®è¡ããäœæ¥ã¯ãŸã ãããããããŸãã å®éãããªãã説æããããšã®å€ãã¯ãJetpackComposeã®èšèšæ¹æ³ãšéåžžã«äŒŒãŠããŸãã ã³ã³ãã€ã©ã®éæ³ãå¿ èŠãªãããç§ã¯ãã®ãã¶ã€ã³ã®å€§ãã¡ã³ã§ã¯ãªãã®ã§ãäœãèµ·ãã£ãŠããã®ãããããã°ããã®ã¯æ¬åœã«é£ããã§ãããå€åããã¯ããªãã®è·¯å°ã«ãããŸããïŒ
ããã«ã¯çžäºã«æä»çãªæ¬²æ±ãããããããããã®ãã°ã®å€ãã®ã³ã¡ã³ãã«åºãã£ãŠããããã§ãã
ãããã¯çžäºã«æä»çã§ã¯ãããŸããã ããã¯ã¯ãããã®ãã¹ãŠãå®è¡ããŸãã ãœãªã¥ãŒã·ã§ã³ã«çŠç¹ãåœãŠãããªãã®ã§ã詳现ã«ã¯ç«ã¡å ¥ããŸãããããã¹ãŠã®ãã§ãã¯ããã¯ã¹ããªã³ã«ããŸãã
åã«ãèšã£ãããã«ãããã§äœããåŸãããã®æè¯ã®æ¹æ³ã¯ãçŽé¢ããŠããåé¡ãç解ã§ããæ¹æ³ã§èª¬æãããã¹ãŠã®ããŒãºã1ãæã§èª¬æãããŠãŒã¹ã±ãŒã¹ã§èª¬æããããšã§ãã
ç§ã¯ãŸã ãã®ãããã³ã¡ã³ãããããã©ã®ããã«å€±æããã®ãç解ã§ããŸããã
ä»ã®äººã«äœãã¯ã£ããããŠããªãã®ããç§ã«ã¯ããããŸããã
å®éãããªãã説æããããšã®å€ãã¯ãJetpackComposeã®èšèšæ¹æ³ãšéåžžã«äŒŒãŠããŸãã ã³ã³ãã€ã©ã®éæ³ãå¿ èŠãªãããç§ã¯ãã®ãã¶ã€ã³ã®å€§ãã¡ã³ã§ã¯ãªãã®ã§ãäœãèµ·ãã£ãŠããã®ãããããã°ããã®ã¯æ¬åœã«é£ããã§ãããå€åããã¯ããªãã®è·¯å°ã«ãããŸããïŒ
ç§ã¯ãããããç¥ããªãããç°¡åãªæ€çŽ¢ã§ãç§ã¯_yes_ãšèšãã ããã
ãããã¯çžäºã«æä»çã§ã¯ãããŸããã
äžèšã®ãã¹ãŠã®ç®æ¡æžãã¯ãããã§è§£æ±ºããããšããŠããåé¡ã®äžéšã§ããïŒ
ãããã圌ãã¯ãã¹ãŠã®ããã¯ã¹ããã§ãã¯ããŸã
ããã¯ã¹ããªã¹ãã§ããŸããïŒ
ç§ã¯ãŸã ãã®ãããã³ã¡ã³ãããããã©ã®ããã«å€±æããã®ãç解ã§ããŸããã
ããšãã°ãOPã¯ãåé¡ã¯StatefulWidgetsã«é¢ãããã®ã§ãããšæ瀺çã«è¿°ã¹ãŠããŸããããã®åé¡ã«é¢ããæè¿ã®ã³ã¡ã³ãã®1ã€ã¯ãStatelessWidgetsã§æ©èœããªãã£ããããç¹å®ã®ææ¡ã¯é©åã§ã¯ãªããšè¿°ã¹ãŸããã
OPã§ããªãã¯èšãïŒ
State
ããžãã¯ãåå©çšããããšã¯å°é£ã§ãã æçµçã«è€éã§æ·±ããã¹ããããbuild
ã¡ãœããã«ãªãããè€æ°ã®ãŠã£ãžã§ããéã§ããžãã¯ãã³ããŒããŠè²Œãä»ããå¿ èŠããããŸãã
ãããã£ãŠããããããèŠä»¶ã«ã¯æ¬¡ã®ãã®ãå«ãŸããŠãããšæããŸãã
æåã®ãã€ã³ãïŒãã¹ãã£ã³ã°ã«ã€ããŠïŒã¯åé¡ãªãããã§ãã æ·±ããã¹ãããããã®ãå®è¡ããå¿ èŠãããããšã瀺åããããšã¯ããŠããŸããã ïŒãšã¯ãããäœãæ·±ããã¹ããããŠãããã«ã€ããŠã¯æèŠãåãããå¯èœæ§ããããŸããããã¯ããã§ã¯å®çŸ©ãããŠããŸãããåŸã§ä»ã®ã³ã¡ã³ãã¯ããã«ããŒãæ·±ããã¹ããããã³ãŒããåŒãèµ·ããããšã瀺åããŠããŸãããç§ã®çµéšã§ã¯ããã«ããŒã¯ããªãåªããŠããŸãã
2çªç®ã®ãã€ã³ãã¯ãåé·æ§ããªããšããèŠä»¶ã§ããããã«æãããŸãã ããããããªãã¯ãããåé·æ§ã«ã€ããŠã§ã¯ãªãããšãäœåºŠã説æããŸããã
OPãè¡ã次ã®ã¹ããŒãã¡ã³ãã¯ãåé¡ã説æããŠããŸãã
State
ããžãã¯ãè€æ°ã®StatefulWidget
ãŸããã£ãŠåå©çšããããšã¯ããã®ããžãã¯ãè€æ°ã®ã©ã€ããµã€ã¯ã«ã«äŸåããããã«ãªããšããã«éåžžã«å°é£ã«ãªããŸãã
æ£çŽãªãšããããããäœãæå³ããã®ãæ¬åœã«ããããŸããã ç§ã«ãšã£ãŠãé£ããããšã¯ãéåžžãç解ãã«ããè€éãªããžãã¯ãããããå«ãŸããŠããããšãæå³ããŸãããã©ã€ããµã€ã¯ã«ã€ãã³ãã®å²ãåœãŠãç Žæ£ãããã³å¯Ÿå¿ã¯éåžžã«ç°¡åã§ãã åé¡ãäžãã次ã®ã¹ããŒãã¡ã³ãïŒããã§ã¯ããè€éã§ã¯ãªãããšæ瀺çã«èª¬æãããŠãããããããããåé¡ã®èª¬æã§ã¯ãªãäŸãã¹ãããããŠããŸãïŒã¯æ¬¡ã®ãšããã§ãã
åé¡ã¯ããã®ã¢ãããŒããæ¡åŒµããããšãã«å§ãŸããŸãã
ããã¯ããéåžžã«é£ããããšã¯ãéåžžã«åé·ããæå³ãããè€éã§ã¯ãªããäŸãšãéåžžã«é£ãããã®äŸã®å¯äžã®éãã¯ãåæ§ã®ã³ãŒããå€æ°åºçŸããããšããçããããšã瀺åããŸããã ãäŸãã¹ã±ãŒãªã³ã°ããçµæã¯ãæåéããåãã³ãŒããäœåºŠãçºçãããšããããšã§ãïŒã€ãŸããåé·æ§ãå®åã³ãŒãïŒã
ããã¯ãåé¡ã説æãã次ã®ã¹ããŒãã¡ã³ãã«ãã£ãŠããã«ãµããŒããããŸãã
ãã®ããžãã¯ãã©ãã«ã§ãã³ããŒããŠè²Œãä»ãããšãæ©èœãããŸãããã³ãŒãã«åŒ±ç¹ãçããŸãã
- æé ã®1ã€ãæžãçŽãã®ãå¿ããã¡ã§ãïŒ
dispose
åŒã³åºããå¿ãããªã©ïŒ
ã³ãŒããã³ããŒããŠè²Œãä»ãããšãã«åé·æ§ããããããééããç¯ãããããããããããéåžžã«é£ããã®ã§ããããã ããããç¹°ãè¿ãã«ãªããŸãããç§ããåé·æ§ããšè¡šçŸãããã®åé¡ã«å¯ŸåŠããããšãããšããåé¡ã¯åé·æ§ã§ã¯ãªããšãã£ããããŸããã
- ã³ãŒãã«å€ãã®ãã€ãºãè¿œå ããŸã
ç¹°ãè¿ãã«ãªããŸãããããã¯ç§ã«åé·æ§/ãã€ã©ãŒãã¬ãŒããèšã£ãŠããããã«èãããŸãããããã¯ããã§ã¯ãªããšèª¬æããŸããã
OPã®æ®ãã®éšåã¯ãæ°ã«å ¥ããªã解決çã説æããŠããã ããªã®ã§ãããããåé¡ã説æããŠããŸããã
ããã¯ãOPãåé¡ã説æã§ããªãæ¹æ³ã説æããŠããŸããïŒ OPå ã§å®éã«åé¡ã説æããŠãããã®ã¯ãã¹ãŠåé·æ§ã説æããŠããããã«èŠããŸããããããåé¡ã§ãããšææ¡ãããã³ã«ãããã§ã¯ãªããå¥ã®åé¡ããããšèšããŸãã
誀解ã¯èšèã®æå³ã«åž°çãããšæããŸãã
äŸãã°ïŒ
ã³ãŒãã«å€ãã®ãã€ãºãè¿œå ããŸã
ç¹°ãè¿ãã«ãªããŸãããããã¯ç§ã«åé·æ§/ãã€ã©ãŒãã¬ãŒããèšã£ãŠããããã«èãããŸãããããã¯ããã§ã¯ãªããšèª¬æããŸããã
ãã®ç¹ã¯ã controller.dispose()
ã®æ°ã§ã¯ãªãããããã®ã³ãŒãè¡ãèªè
ã«ãããã䟡å€ã§ãã
ãã®ç·ã¯åžžã«ããã«ããã¹ãã§ãããåžžã«åãã§ãã ãã®ããããªãŒããŒã«å¯Ÿãããã®å€ã¯ã»ãšãã©nullã§ãã
éèŠãªã®ã¯ããã®ç·ã®ååšã§ã¯ãªãããã®äžåšã§ãã
åé¡ã¯ããã®ãããªcontroller.dispose()
ãå€ããã°å€ãã»ã©ãdisposeã¡ãœããã§å®éã®åé¡ãèŠéãå¯èœæ§ãé«ããªãããšã§ãã
ã³ã³ãããŒã©ãŒã1ã€ãå»æ£ã0ã®å Žåãç°¡åã«ãã£ããã§ããŸãã
100åã®ã³ã³ãããŒã©ãŒãš99åã®å»æ£ãããå Žåãäžè¶³ããŠããã³ã³ãããŒã©ãŒãèŠã€ããã®ã¯å°é£ã§ãã
次ã«ã次ã®ããã«ãªããŸãã
ã³ãŒããã³ããŒããŠè²Œãä»ãããšãã«åé·æ§ããããããééããç¯ãããããããããããéåžžã«é£ããã®ã§ããããã ããããç¹°ãè¿ãã«ãªããŸãããç§ããåé·æ§ããšè¡šçŸãããã®åé¡ã«å¯ŸåŠããããšãããšããåé¡ã¯åé·æ§ã§ã¯ãªããšãã£ããããŸããã
åã®ãã€ã³ãã§è¿°ã¹ãããã«ãã³ãŒãã®ãã¹ãŠã®è¡ãçããããã§ã¯ãããŸããã
æ¯èŒãããšïŒ
+ T state;
<strong i="24">@override</strong>
void initState() {
super.initState();
+ state = widget.valueNotifier.value;
+ widget.valueNotifier.addListener(_listener);
}
+ void _listener() => seState(() => state = widget.valueNotifier.value);
void dispose() {
+ widget.valueNotifier.removeListener(_listener);
super.dispose();
}
察ïŒ
+ ValueListenableBuilder<T>(
+ valueListenable: widget.valueNotifier,
+ builder: (context, value, child) {
+ },
+ );
ãã®å Žåããããã®ã¹ããããã¯äž¡æ¹ãšãåãè¡æ°ãæã¡ãåãããšãè¡ããŸãã
ãã ãã ValueListenableBuilder
ãæãŸããã§ãã
ãã®çç±ã¯ãéèŠãªã®ã¯è¡æ°ã§ã¯ãªãããããã®è¡ãäœã§ããããšããããšã§ãã
æåã®ã¹ããããã«ã¯æ¬¡ã®ãã®ããããŸãã
2çªç®ã®ã¹ããããã«ã¯æ¬¡ã®ãã®ããããŸãã
ããã«ãããValueListenableBuilderã_simpler_ã«ãªããŸãã
ãããã®è¡ãèšã£ãŠããªãããšããããŸãïŒ
ValueListenableBuilderã¯ãæéã®çµéã«äŒŽãvalueListenable
å€åãåŠçããŸãã
widget.valueNotifier
ãæéã®çµéãšãšãã«å€åããªãã·ããªãªã§ããåé¡ã¯ãããŸããã
ããæ¥ããã®å£°æã¯å€ãããããããŸããã ãã®å ŽåãValueListenableBuilderã¯æ°ããåäœãé©åã«åŠçããŸãããæåã®ã¹ããããã§ã¯ãã°ãçºçããŠããŸãã
ãããã£ãŠãValueListenableBuilderã¯åçŽã§ããã ãã§ãªãããŸã£ããåãè¡æ°ã§ãã³ãŒãã®å€æŽã«å¯Ÿããèæ§ãé«ããªããŸãã
ããã§ãValueListenableBuilderãæãŸãããšããããšã«ã¯åæã§ãããšæããŸãã
åé¡ã¯ãããã¹ãŠã®åå©çšå¯èœãªç¶æ
ããžãã¯ã«ValueListenableBuilderãšåçã®ãã®ããªãã®ã¯ãªãã§ããïŒãã§ãã
ããšãã°ã次ã®ä»£ããã«ïŒ
final controller = TextEditingController(text: 'hello world');
...
controller.dispose();
ç§ãã¡ã¯æã£ãŠããã§ãããïŒ
TextEditingControllerBuilder(
initialText: 'hello world',
builder: (context, controller) {
},
);
initialText
ãžã®å€æŽãããããªããŒãã§ãããšããè¿œå ã®å©ç¹ããããŸãã
ãã®äŸã¯å°ãäºçŽ°ãªããšãããããŸãããããã®ååãå°ãé«åºŠãªåå©çšå¯èœãªç¶æ
ããžãã¯ïŒ ModeratorBuilder
ïŒã«äœ¿çšã§ããŸãã
ããã¯å°ããªã¹ããããã§ã¯ãåé¡ãããŸãããã ããããã¢ãããŒããæ¡åŒµãããã®ã§ãããã€ãã®åé¡ãçºçããŸãã
ããšãã°ã次ã®ããã«ã¢ãã«ã管çããŠãã人ãããŸãã
class User {
final ValueNotifier<String> name;
final ValueNotifier<int> age;
final ValueNotifier<Gender> gender;
}
ãããããŠã£ãžã§ããã¯ã name
ã age
ãããã³gender
äž¡æ¹ãäžåºŠã«ãªãã¹ã³ãããå ŽåããããŸãã
ã€ãŸãã次ã®ããšãè¡ãå¿
èŠããããŸãã
return ValueListenableBuilder<String>(
valueListenable: user.name,
builder: (context, userName, _) {
return ValueListenableBuilder<int>(
valueListenable: user.age,
builder: (context, userAge, _) {
return ValueListenableBuilder<Gender>(
valueListenable: user.gender,
builder: (context, userGender, _) {
return Text('$userGender. $userName ($userAge)');
},
);
},
);
},
);
ããã¯æããã«çæ³çã§ã¯ãããŸããã initState
/ dispose
å
ã®æ±æãé€å»ããŠã build
ã¡ãœãããæ±æããŸããã
ïŒäŸã®ããã«Listenable.merge
ãç¡èŠããŸããããããã§ã¯éèŠã§ã¯ãããŸãããæ§æã«ã€ããŠã§ãïŒ
Builderãåºç¯å²ã«äœ¿çšããå Žåããã®æ£ç¢ºãªã·ããªãªã§èªåèªèº«ãç°¡åã«ç¢ºèªã§ããŸãã Listenable.merge
çžåœãããã®
ã«ã¹ã¿ã ãã«ããŒãæžãã®ã¯é¢åã§ã
Builderãäœæããç°¡åãªè§£æ±ºçã¯ãããŸããã ããã§ã¯ãªãã¡ã¯ã¿ãªã³ã°ããŒã«ã¯åœ¹ã«ç«ã¡ãŸãããåã«ããã«ããŒãšããŠæœåºãããããšã¯ã§ããŸããã
ããã«ãããã¯å¿
ãããçŽæçã§ã¯ãããŸããã ã«ã¹ã¿ã ãã«ããŒãäœæããããšã¯ã人ã
ãæåã«èããããšã§ã¯ãããŸãããç¹ã«ãå€ãã®äººãå®åæã«å察ããã§ãããïŒç§ã¯ããã§ã¯ãããŸãããïŒã
人ã ã¯ã«ã¹ã¿ã ã®ç¶æ 管çãœãªã¥ãŒã·ã§ã³ãäœæããå¯èœæ§ãé«ããæçµçã«ã¯äžè¯ã³ãŒãã«ãªãå¯èœæ§ããããŸãã
ãã«ããŒã®ããªãŒãæäœããã®ã¯é¢åã§ã
åã®äŸã§ValueListenableBuilder
ãåé€ããããæ°ããäŸãè¿œå ããããšããŸãããããã¯ç°¡åã§ã¯ãããŸããã
ã³ãŒããã³ã³ãã€ã«ãããªãçç±ãç解ããããã«ãïŒïŒãš{}ã®ã«ãŠã³ãã«æ°åè²»ããããšãã§ããŸãã
ä»è¿°ã¹ãBuilderã®åé¡ã解決ããããã®ããã¯ããããŸãã
åã®äŸãããã¯ã«ãªãã¡ã¯ã¿ãªã³ã°ãããšã次ã®ããã«ãªããŸãã
final userName = useValueListenable(user.name);
final useAge = useValueListenable(user.age);
final useGender = useValueListenable(user.gender);
return Text('$userGender. $userName ($userAge)');
以åã®åäœãšåãã§ãããã³ãŒãã«ç·åœ¢ã€ã³ãã³ããè¿œå ãããŸããã
ã€ãŸãïŒ
ããã¯ã¡ã€ã³ã®provider
ã奜ããªãã®ã®1ã€ã§ãã MultiProvider
å°å
¥ããããšã§ãå€ãã®ãã¹ããåé€ããŸããã
åæ§ã«ã initState
/ dispose
ã¢ãããŒããšã¯å¯Ÿç
§çã«ãããããªããŒãã®æ©æµãåããŸãã
æ°ããuseValueListenable
ãè¿œå ããå Žåãå€æŽã¯ããã«é©çšãããŸãã
ãããŠãã¡ãããåå©çšå¯èœãªããªããã£ããæœåºããæ©èœã¯ãŸã ãããŸãã
String useUserLabel(User user) {
final userName = useValueListenable(user.name);
final useAge = useValueListenable(user.age);
final useGender = useValueListenable(user.gender);
return '$userGender. $userName ($userAge)';
}
Widget build(context) {
final label = useUserLabel(user);
return Text(label);
}
ãã®ãããªå€æŽã¯extract as function
ã§èªååã§ããã»ãšãã©ã®ã·ããªãªã§æ©èœããŸãã
ããã¯ããªãã®è³ªåã«çããŸããïŒ
ãã¡ããã ãããããã®ãããªãã®ã®åé¡ã¯ãå®éã«æ£ããããšãè¡ãã®ã«ååãªæ å ±ããªãããšã§ãã äŸãã°ïŒ
Widget build(context) {
if (random.nextBool())
final title = useLabel(title);
final label = useLabel(name);
return Text(label);
}
...æ¬åœã«çŽããããæ¹æ³ã§ãã°ãçºçããããšã«ãªããŸãã
ã³ã³ãã€ã©ã®éæ³ã§ãããåé¿ããããšãã§ããŸããïŒComposeã¯ãããè¡ãæ¹æ³ã§ãïŒãFlutterã®å Žåãåºæ¬çãªèšèšäžã®æ±ºå®ã®äžéšã«éåããŸãã ããŒã䜿çšããŠåé¿ããããšã¯ã§ããŸãããããã©ãŒãã³ã¹ãå€§å¹ ã«äœäžãïŒå€æ°ã«ãã¯ã¢ããã«ã¯ãããã«ãã¯ã¢ãããããã·ã¥ãªã©ãå«ãŸããããïŒãFlutterã®åºæ¬çãªèšèšç®æšã®äžéšã«éåããŸãã
以åã«ææ¡ããããããã£ãœãªã¥ãŒã·ã§ã³ããŸãã¯ãããã掟çãããã®ã¯ããã¹ãŠã®ã³ãŒãã1ãæã«ãŸãšãããšããåè¿°ã®ç®æšãéæããªãããã³ã³ãã€ã©ã®éæ³ãåé¿ããŠããããã§ãã ãªããããããŸããããªãã®ããç§ã«ã¯ããããããŸããã ïŒæããã«ãdidChangeDependenciesãªã©ã«ãããã¯ããŠå®å šãªãœãªã¥ãŒã·ã§ã³ã«ããããã«æ¡åŒµãããŸããïŒïŒããã©ãŒãã³ã¹èŠä»¶ã«éåããããããããåºæ¬ãã¬ãŒã ã¯ãŒã¯ã«é 眮ããŸãããïŒ
ããªããèšãããã«ãçºçããå¯èœæ§ã®ãããã°ãåå ã§ãããã¯ãæ¡ä»¶ä»ãã§åŒã³åºãã¹ãã§ã¯ãããŸããã 詳现ã«ã€ããŠã¯ãReactJSã®Rules ofHooksããã¥ã¡ã³ããåç
§ããŠãã ããã åºæ¬çãªèŠç¹ã¯ããããã®å®è£
ã§ã¯åŒã³åºãé åºã«ãã£ãŠè¿œè·¡ããããããæ¡ä»¶ä»ãã§äœ¿çšãããšãã®åŒã³åºãé åºãå£ããæ£ãã远跡ã§ããªããªããšããããšã§ãã ããã¯ãé©åã«äœ¿çšããã«ã¯ãæ¡ä»¶ä»ãããžãã¯ãªãã§build
ã®ãããã¬ãã«ã§ããã¯ãåŒã³åºããŸãã JSããŒãžã§ã³ã§ã¯ãããªãã¯æ»ã£ãŠããŸã
const [title, setTitle] = useLabel("title");
Dartã«çžåœãããã®ãåæ§ã§ãããJSã®ããã«è§£åããªããããé·ããªããŸãã
var titleHook = useLabel("title");
String title = titleHook.property;
Function setTitle = titleHook.setter;
æ¡ä»¶ä»ãããžãã¯ãå¿
èŠãªå Žåã¯ããã«ãã¡ãœããã§title
ã䜿çšããããšã決å®ã§ããŸããããã¯ãåŒã³åºãé åºãåŒãç¶ãä¿æãããããã§ãã ããªããæèµ·ãããããã®åé¡ã®å€ãã¯ãç§ãäžã§ãªã³ã¯ããããã¯ããã¥ã¡ã³ãã§èª¬æãããŠããŸãã
ãã¡ããã ãããŠãããªãã¯ããã±ãŒãžã§ãããè¡ãããšãã§ããŸãã ãã®ãããªèŠä»¶ã¯ç§ãã¡ã®èšèšå²åŠã«éåããã ãããšèšã£ãŠããã ãã§ãããã®ãããFlutterãã¬ãŒã ã¯ãŒã¯ã«ãããè¿œå ããŸããã ïŒå ·äœçã«ã¯ãèªã¿ããããšãããã°å¯èœæ§ãæé©åããŸããã³ãŒããæ©èœããŠããããã«èŠããŸãããæ¡ä»¶ä»ãïŒã³ãŒãã§ã¯æããã§ãªãå ŽåããããŸãïŒãæ©èœããªãå Žåããããããã³ã¢ãã¬ãŒã ã¯ãŒã¯ãïŒ
ãããã°/æ¡ä»¶ä»ãã®åäœã¯åé¡ã§ã¯ãããŸããã ãã®ãããã¢ãã©ã€ã¶ãŒãã©ã°ã€ã³ãéèŠã§ãã ãã®ãããªãã©ã°ã€ã³ã¯æ¬¡ã®ããã«ãªããŸãã
useMyFunction
ãšããååãªãã§ããã¯ã䜿çšããå Žåã«èŠåããã¯ãã¹ãŠã®æœåšçãªééããã«ããŒããŠããŸãã Reactã¯ããããå®è¡å¯èœãªããšã§ããããšã蚌æããŸããã
次ã«ã次ã®ãããªã¡ãªããããããŸãã
èšç®ãããç¶æ ã«ã€ããŠã¯ãããã¯ã¯ãªããžã§ã¯ãã®ã€ã³ã¹ã¿ã³ã¹ããã£ãã·ã¥ããã®ã«éåžžã«åŒ·åã§ãã ããã¯ããã©ã¡ãŒã¿ãŒãå€æŽãããå Žåã«ã®ã¿ãŠã£ãžã§ãããåæ§ç¯ããããã«äœ¿çšã§ããŸãã
ããšãã°ã次ã®ããã«ããããšãã§ããŸãã
class Example extends HookWidget {
final int userId;
Widget build(context) {
// Calls fetchUser whenever userId changes
// It is the equivalent to both initState and didUpdateWidget
final future = useMemo1(() => fetchUser(userId), userId);
final snapshot = useFuture(future);
if (!snapshot.hasData)
return Text('loading');
return Text(snapshot.data.name);
}
}
ãã®ãããªuseMemo
ããã¯ã䜿çšãããšãããã©ãŒãã³ã¹ãç°¡åã«æé©åããinitãšupdateã®äž¡æ¹ã宣èšçã«åŠçã§ããããããã°ãåé¿ã§ããŸãã
ããã¯ã Property
/ context.onDispose
ææ¡ãèŠéããŠãããã®ã§ãã
ããžãã¯ãã©ã€ããµã€ã¯ã«ã«ç·å¯ã«çµåããããã³ãŒããValueNotifier
è€éåãããããªãéãã宣èšåã®ç¶æ
ã«äœ¿çšããããšã¯å°é£ã§ãã
ValueGetter
ææ¡ãå®çšçã§ãªãçç±ã®è©³çŽ°ïŒ
ãªãã¡ã¯ã¿ãªã³ã°ãå¿ èŠãªå ŽåããããŸãã
final int userId;
Widget build(context) {
final future = useMemo1(() => fetchUser(userId), userId);
ã®äžãžïŒ
Widget build(context) {
final userId = Model.of(context).userId;
final future = useMemo1(() => fetchUser(userId), userId);
useMemo
ã¯ã©ã€ããµã€ã¯ã«ã«é¢é£ä»ããããŠããªããããããã¯ã䜿çšãããšããã®å€æŽã¯åé¡ãªãæ©èœããŸãã
ãããã Property
+ ValueGetter
å Žåããããæ©èœãããã«ã¯Property
ã®å®è£
ãå€æŽããå¿
èŠããããŸããããã¯ã Property
ã³ãŒããè€æ°ã®å Žæã§åå©çšã ãã®ãããåå©çšæ§ãåã³å€±ãããŸããã
FWIWãã®ã¹ããããã¯æ¬¡ã®ãã®ãšåçã§ãã
class Example extends StatefulWidget {
final int userId;
<strong i="45">@override</strong>
_ExampleState createState() => _ExampleState();
}
class _ExampleState extends State<Example> {
Future<User> future;
<strong i="46">@override</strong>
void initState() {
super.initState();
future = fetchUser(widget.userId);
}
<strong i="47">@override</strong>
void didUpdateWidget(Example oldWidget) {
super.didUpdateWidget(oldWidget);
if (oldWidget.userId != widget.userId) {
future = fetchUser(widget.userId);
}
}
<strong i="48">@override</strong>
Widget build(BuildContext context) {
return FutureBuilder<User>(
future: future,
builder: (context, snapshot) {
if (!snapshot.hasData)
return Text('loading');
return Text(snapshot.data.name);
},
);
}
}
@rrousselGitãèšåããŠããã®ãšåãåé¡ã解決ããã ãã§ãªããèªã¿ããããšãããã°å¯èœæ§ã念é ã«çœ®ãã解決çãèŠã€ããå¿ èŠããããšæããŸãã Vueã«ã¯ç¬èªã®å®è£ ããããæ¡ä»¶ãåŒã³åºãé åºãReactã®ããã«ãã°ãåŒãèµ·ãããªãå Žåã«ãæ¢ããŠãããã®ãšããäžèŽããå¯èœæ§ããããŸãã
ãã¶ã次ã®ã¹ãããã¯ãVueãVueã®å¶çŽãäžããããããŒãžã§ã³ãäœæããã®ãšåãããã«ãFlutterã®å¶çŽãäžããããããã®ãã¬ãŒã ã¯ãŒã¯ã®ããã¯ã®ããŒãžã§ã³ã§ããFlutterã«åºæã®ãœãªã¥ãŒã·ã§ã³ãäœæããããšã§ãã ç§ã¯Reactã®ããã¯ãå®æçã«äœ¿çšããŠããŸãããã¢ãã©ã€ã¶ãŒãã©ã°ã€ã³ãæã£ãŠããã ãã§ã¯äžååãªå Žåããããããããèšèªã«ãã£ãšçµ±åããå¿ èŠããããŸãã
ãããã«ãããã³ã³ã»ã³ãµã¹ãåŸããããšã¯æããŸããã äœãèªãããã«ã€ããŠãæèŠãåããªãããã§ã
念ã®ããããããå ±æããŠããã®ã¯ãã³ãã¥ããã£ã«ãã®åé¡ã«é¢ããåé¡ãããããšãç¥ã£ãŠããããã§ãã ç§ã¯å人çã«ãFlutterãããã«ã€ããŠäœãããªããã©ãããæ°ã«ããŸããïŒç§ã¯ãã®çš®ã®æ²ãããšæããŸããïŒïŒç§ãã¡ãæã£ãŠããéãïŒ
ç§ã匷ããå§ãããããã¯ãã©ã°ã€ã³ãè¿œæ±ãããããããã€ãã®åé¡ãçºçããŠããå Žåã¯ããããã®åé¡ã«ã€ããŠåé¡ãæåºãããããã®åé¡ãä¿®æ£ããããã«PRãæåºããããšããå§ãããŸãã åãã§ãååãããŠããã ããŸãã
ããã¯ã以åã®Property
ã¢ã€ãã¢ã®æ°ããããŒãžã§ã³ã§ãã ããã¯didUpdateWidgetãšç Žæ£ãåŠçããŸãïŒãããŠdidChangeDependenciesã®ãããªä»ã®ãã®ãåŠçããããã«ç°¡åã«äœãããšãã§ããŸãïŒ; ããããªããŒãããµããŒãããŠããŸãïŒããããã£ãšããããªããŒããç»é²ããã³ãŒããå€æŽã§ããæ£ããããšãå®è¡ããŸãïŒã æ瀺çãªåãå¿
èŠãšããã«åå®å
šã§ãïŒæšè«ã«äŸåããŸãïŒã ããããã£ã®å®£èšãšäœ¿çšæ³ãé€ããŠããã¹ãŠã1ã€ã®å Žæã«ãããããã©ãŒãã³ã¹ã¯é©åºŠã«åªããŠããå¿
èŠããããŸãïŒãã ããããåé·ãªæ¹æ³ã»ã©åªããŠããããã§ã¯ãããŸããïŒã
ããããã£/ããããã£ãããŒãžã£ãŒïŒ
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
typedef InitStateCallback<T> = T Function(T oldValue);
typedef DidUpdateWidgetCallback<T, W extends StatefulWidget> = T Function(W oldWidget);
class Property<T, W extends StatefulWidget> {
Property({
T value,
this.initState,
this.didUpdateWidget,
this.dispose,
}) : _value = value;
T get value {
assert(_value != null);
return _value;
}
T _value;
final InitStateCallback<T> initState;
void _initState(Property<T, W> oldProperty) {
if (initState != null)
_value = initState(oldProperty?.value);
assert(_value != null);
}
final DidUpdateWidgetCallback<T, W> didUpdateWidget;
void _didUpdateWidget(StatefulWidget oldWidget) {
if (didUpdateWidget != null) {
final T newValue = didUpdateWidget(oldWidget);
if (newValue != null)
_value = newValue;
}
}
final ValueSetter<T> dispose;
void _dispose() {
if (dispose != null)
dispose(value);
}
}
mixin PropertyManager<W extends StatefulWidget> on State<W> {
final Set<Property<Object, W>> _properties = <Property<Object, W>>{};
bool _ready = false;
Property<T, W> register<T>(Property<T, W> oldProperty, Property<T, W> property) {
assert(_ready);
if (oldProperty != null) {
assert(_properties.contains(oldProperty));
_properties.remove(oldProperty);
}
assert(property._value == null);
property._initState(oldProperty);
_properties.add(property);
return property;
}
<strong i="9">@override</strong>
void initState() {
super.initState();
_ready = true;
initProperties();
}
<strong i="10">@override</strong>
void reassemble() {
super.reassemble();
initProperties();
}
<strong i="11">@protected</strong>
<strong i="12">@mustCallSuper</strong>
void initProperties() { }
<strong i="13">@override</strong>
void didUpdateWidget(W oldWidget) {
super.didUpdateWidget(oldWidget);
for (Property<Object, W> property in _properties)
property._didUpdateWidget(oldWidget);
}
<strong i="14">@override</strong>
void dispose() {
_ready = false;
for (Property<Object, W> property in _properties)
property._dispose();
super.dispose();
}
}
䜿çšæ¹æ³ã¯æ¬¡ã®ãšããã§ãã
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'properties.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
<strong i="18">@override</strong>
Widget build(BuildContext context) {
return MaterialApp(
home: Example(userId: 1),
);
}
}
class User {
User(this.name);
final String name;
}
Future<User> fetchUser(int userId) async {
await Future.delayed(const Duration(seconds: 2));
return User('user$userId');
}
class Example extends StatefulWidget {
Example({ Key key, this.userId }): super(key: key);
final int userId;
<strong i="19">@override</strong>
_ExampleState createState() => _ExampleState();
}
class _ExampleState extends State<Example> with PropertyManager {
Property future;
<strong i="20">@override</strong>
void initProperties() {
super.initProperties();
future = register(future, Property(
initState: (_) => fetchUser(widget.userId),
didUpdateWidget: (oldWidget) {
if (oldWidget.userId != widget.userId)
return fetchUser(widget.userId);
}
));
}
<strong i="21">@override</strong>
Widget build(BuildContext context) {
return FutureBuilder<User>(
future: future.value,
builder: (context, snapshot) {
if (!snapshot.hasData) return Text('loading');
return Text(snapshot.data.name);
},
);
}
}
䟿å®äžãAnimationControllersãªã©ã®æºåãããPropertyãµãã¯ã©ã¹ãäœæã§ããŸãã
ãããããState.buildã¡ãœããã§ãæ©èœããããŒãžã§ã³ãäœæã§ããŸã...
@HixieãããŒãã«ã«ããããçåã®ããã€ããå
±æããŸãã äžæ¹ã§ãããã¯ã«ã¯æãããªå©ç¹ããããããªãã®æ°ã®éçºè
ããããæ°ã«å
¥ã£ãŠããããã§ãã
@timsneathãææ¡ããããã±ãŒãžã¢ãããŒãã«é¢ããç§ã®åé¡ã¯ãããã¯ã䜿çšããã³ãŒãããããã¯ã䜿çšããªãã³ãŒããšã¯åçã«ç°ãªãããã«èŠããããšã§ãã 圌ãã圌ããå
¬åŒã®ã«ãã³ã«å
¥ããªããšãFlutterã®ã«ãã³ããã©ã£ãã ãã§ã¯èªããªãFlutterã³ãŒãã«ãªã£ãŠããŸããŸãã
ããã±ãŒãžããã¬ãŒã ã¯ãŒã¯ã®å¿çæ§ã§ããã¯ãã®ãã®ãå®è£
ãå§ãããšãæ°ããã³ãŒãããŒã¹ã®åŠç¿ãå°é£ã«ããããŸããŸãªFlutteræ¹èšãåŸãããŸãã ã ããç§ã«ãšã£ãŠã¯ãFlutterã®äžéšã«ãªã£ãç¬éã«ããã¯ã䜿ãå§ããã§ãããã
ããã¯ãããªãŒãºãããããã±ãŒãžã«é¢ããç§ã®çŸåšã®èŠæ¹ãšãã䌌ãŠããŸãã ç§ã¯ãã®æ©èœã倧奜ãã§ãããUnionãšããŒã¿ã¯ã©ã¹ãDartã®äžéšã§ãªãéããã³ãŒãããŒã¹ã«å«ããããããŸãããã³ãŒããèªã¿ã«ãããªãããã§ãã
@escamoteurããããŸãããããŠã£ãžã§ããã®åäœãæ ¹æ¬çã«å€ããããšãææ¡ããŠããŸããïŒ ãããšããç¹å®ã®æ°ããèœåãããã¹ãã ãšææ¡ããŠããŸããïŒ ã³ã¢ãã¬ãŒã ã¯ãŒã¯ãå€æŽããã«ããã¯ãäžèšã®ããããã£ææ¡ã®ãããªããšãã©ã®ããã«å¯èœã§ããããèãããšãå®éã«äœãå€æŽããããã¯ç§ã«ã¯ããããŸããã
ææ¡ãããå€æŽèªäœã«ã€ããŠã®äŒè©±ãšã¯çŽäº€ããŠããŸããã @ escamoteur ã @ rrousselGitãªã©ãããããä»ã®å Žæã§èããããšã¯ããã¬ãŒã ã¯ãŒã¯ã§ããããšãç¹å®ã®æ£åœæ§ã確ç«ããããã®éèŠãªæ¹æ³ãšããŠèªèãããŠããããšã ãšæããŸãã¢ãããŒãã åæããªãå Žåã¯èšæ£ããŠãã ããã
ç§ã¯ãã®èãæ¹ãç解ããŠããŸã-ãã¬ãŒã ã¯ãŒã¯ã«å«ãŸããããšããçããããšãããããããã®ã§ïŒããšãã°ãDartPadã¯çŸåšãµãŒãããŒãã£ã®ããã±ãŒãžããµããŒãããŠããªããããäžéšã®é¡§å®¢ã¯NPMã§æžã蟌ãŸããåŸã«äŸåããããã±ãŒãžã®æ°ã«äžå®ãæããŠããŸããããã¯ãããå ¬åŒãã«æããŸããããã¯null-safetyã®ãããªå€æŽã§åé²ããããšãä¿èšŒãããŠããŸãïŒã
ãã ããå«ããã«ã¯ããªãã®ã³ã¹ããããããŸããç¹ã«ãã¢ãããŒããšAPIãå¿ èŠã«ãªããŸãã ãã®ãããç¹ã«å šäŒäžèŽã®åæããªãå ŽåïŒç¶æ 管çãåç §ïŒãé²åã®å¯èœæ§ãããå ŽåããŸãã¯ããã±ãŒãžãšåããããç°¡åã«äœããè¿œå ã§ããå Žåã¯ãè¿œå ãããã®ã«å¯ŸããŠéåžžã«é«ãåºæºãä¿æããŸãã
ããã±ãŒãžãã¡ãŒã¹ãã®å²åŠãææžåããå¿ èŠãããã®ã§ã¯ãªãããšæããŸãããããã§ããç¶æ ããžãã¯ã®åå©çšãæ¹åããããã«äœãå€æŽããããã«ã€ããŠã®è°è«ãšã¯å¥ã®ãã®ã§ãã
ããã±ãŒãžããªã·ãŒã¯ããã«èšèŒãããŠããŸãïŒ https ïŒ
ç§ã¯ããã±ãŒãžãã¡ãŒã¹ãã®ã¢ãããŒããå®å
šã«ç解ããŠããããããéèŠãªããšã§ããããšã«åæããŸãã
ããããç§ã¯ãŸããããã€ãã®åé¡ã¯ããã±ãŒãžã§ã¯ãªãã³ã¢ã§è§£æ±ºããå¿
èŠããããšä¿¡ããŠããŸãã
ãã®ããã provider
ãFlutterã«ããŒãžããå¿
èŠããããšã¯äž»åŒµããŠããŸãããããã®åé¡ã¯ãFlutterããã€ãã£ãã«è§£æ±ºããå¿
èŠãããåé¡ã説æããŠãããšèããŠããŸãïŒãã¡ãããå¿
ãããããã¯ã䜿çšããå¿
èŠã¯ãããŸããïŒã
ãããã€ããŒãšãšãã«ãFlutterã¯ãã®çš®ã®åé¡ã解決ããããã®çµã¿èŸŒã¿ããªããã£ãã§ããAttachedWidgetsãåºè·ããŸãã
ãããã€ããŒã¯ãããããããè¯ãããã®ã«ããããã«ãäžéšã«æèŠã®ããã¬ã€ã€ãŒãè¿œå ããã ãã§ãã
ããã¯ãéããŸãã ãããã¯ããªããã£ãã§ãã ãããã¯ãç¹å®ã®åé¡ã«å¯Ÿããéãããªã³ã®äœã¬ãã«ã®ãœãªã¥ãŒã·ã§ã³ã§ããè€æ°ã®ç¶æ
ã«ããã£ãŠããžãã¯ãåå©çšããŸãã
ãããã¯æçµè£œåã§ã¯ãããŸããããã«ã¹ã¿ã ããã±ãŒãžãæ§ç¯ããããã«äººã
ã䜿çšããããšãæåŸ
ãããŠãããã®ã§ãïŒç§ãhooks_riverpodã§è¡ã£ãããã«ïŒ
äžã§èœæžãããããããã£ã¢ãããŒããããã¯ãšã©ã®ããã«æ¯èŒããããã«ã€ããŠèª°ãã詳现ãªã¬ãã¥ãŒãæäŸã§ããã°ïŒããã§ã®æ¬²æ±ãããã¯ãæºããããŒãºãªã©ãç解ãããšããç¹ã§ïŒç§ã«ãšã£ãŠåœ¹ç«ã¡ãŸãã ïŒããããã£ã®ã¢ã€ãã¢ã«é¢ããç§ã®ç®æšã¯ããã¬ãŒã ã¯ãŒã¯ã®äžã«æèŠãéããŠãè€æ°ã®ç¶æ ã§ããžãã¯ãåå©çšããæ¹æ³ã®åé¡ã解決ããããšã§ããïŒ
ããããã£ã®ææ¡ã§ã¯ããã®åé¡ã®äž»èŠãªç®æšã解決ã§ããªããšæããŸããç¶æ ããžãã¯ã¯ããã©ã¡ãŒã¿ãŒãã©ãããæ¥ãŠãã©ã®ãããªç¶æ³ã§æŽæ°ãããŠããããæ°ã«ããå¿ èŠã¯ãããŸããã
ãã®ææ¡ã¯ããã¹ãŠã®ããžãã¯ã1ã€ã®å Žæã«åã°ã«ãŒãåããããšã«ãããããçšåºŠèªã¿ããããåäžãããŸãã ããããåå©çšæ§ã®åé¡ã解決ããããšã¯ã§ããŸãã
å ·äœçã«ã¯ã以äžãæœåºããããšã¯ã§ããŸããã
Property(
initState: (_) => fetchUser(widget.userId),
didUpdateWidget: (oldWidget) {
if (oldWidget.userId != widget.userId)
return fetchUser(widget.userId);
}
)
ããžãã¯ã¯Example
ãšinitState
+ didUpdateWidget
ãã€ã³ããããŠããããã _ExampleState
ããåãåºããŠå¥ã®ãŠã£ãžã§ããã§åå©çšããŸã
ããã¯ã§ã©ã®ããã«èŠããã§ããããïŒ
Rustã³ãã¥ããã£ã§äŒŒããããªãã®ãèŠãåŸã @ timsneathã«åæããŸãã ã³ã¢ããäœããæœåºããã®ã¯éåžžã«å°é£ã§ããBLoCãã¿ãŒã³ã¯ãããã€ããŒãç»å Žããåã«æå®ãããŠããŸããããçŸåšã¯ãããã€ããŒãæšå¥šããŒãžã§ã³ã§ãã ãããããflutter_hooksã¯åãããã«ãç¥çŠããããããŒãžã§ã³ã§ããå¯èœæ§ããããŸãã å°æ¥ã人ã ãæãã€ããããã¯ã«æ¹åãèŠããããããããªãã®ã§ãç§ã¯ãããèšããŸãã Reactã¯ãä»ããã¯ãæã£ãŠããã®ã§ãå®éã«ããã¯ãå€æŽããããããã¯ããæãåºãããããããšã¯ã§ããŸããã ãããã¯ã³ã¢ã«ãããããã¯ã©ã¹ã³ã³ããŒãã³ããšåãããã«ãæ¬è³ªçã«æ°žä¹ ã«ãµããŒãããå¿ èŠããããŸãã ãããã£ãŠãç§ã¯ããã±ãŒãžå²åŠã«åæããŸãã
åé¡ã¯ãæ¡çšãå°ãªãã人ã ãèªåã«åã£ããã®ã䜿çšããããšã ãšæãããŸãã ããã¯ãç§ãèšãããã«ãflutter_hooksã®äœ¿çšãæšå¥šããããšã§è§£æ±ºã§ããŸãã å€ãã®äººããããã€ããŒã䜿çšããŠããå Žåã§ããç¶æ 管çãœãªã¥ãŒã·ã§ã³ãããã€ããããåæ§ã«èŠãã°ãããã¯å€§ããªåé¡ã§ã¯ãªããããããŸããã ãŸããæ§æå¯èœã§åå©çšå¯èœãªã©ã€ããµã€ã¯ã«ããžãã¯ã®åªãããœãªã¥ãŒã·ã§ã³ãäœæããããã«å¯ŸåŠããå¿ èŠã®ãããä»ã®ãã¬ãŒã ã¯ãŒã¯ã§ã®ããã€ãã®åé¡ãšãèœãšãç©ŽããçµéšããŸããã
ããã¯ã§ã©ã®ããã«èŠããã§ããããïŒ
React / flutter_hooksã«ãã£ãŠåºè·ãããããªããã£ãããã¯ã䜿çšããã«ã次ã®ããšãã§ããŸãã
class FetchUser extends Hook<AsyncSnapshot<User>> {
const FetchUser(this.userId);
final int userId;
<strong i="8">@override</strong>
_FetchUserState createState() => _FetchUserState();
}
class _FetchUserState extends HookState<AsyncSnapshot<User>, FetchUser> {
Future<User> userFuture;
<strong i="9">@override</strong>
void initHook() {
userFuture = fetchUser(hook.userId);
}
void didUpdateHook(FetchUser oldHook) {
if (oldHook.userId != hook.userId)
userFuture = fetchUser(hook.userId);
}
<strong i="10">@override</strong>
User build() {
return useFuture(userFuture);
}
}
次ã«äœ¿çšïŒ
class Example extends HookWidget {
const Example({Key key, this.userId}) : super(key: key);
final int userId;
<strong i="14">@override</strong>
Widget build(BuildContext context) {
AsyncSnapshot<User> user = use(FetchUser(userId));
if (!user.hasData)
return CircularProgressIndicator();
return Text(user.data.name);
}
}
ãã®ç¶æ³ã§ã¯ãããžãã¯ã¯Example
ããã³StatefulWidget
ã®ã©ã€ããµã€ã¯ã«ããå®å
šã«ç¬ç«ããŠããŸãã
ãããã£ãŠã userId
ç°ãªãæ¹æ³ã§ç®¡çããå¥ã®ãŠã£ãžã§ããã§åå©çšã§ããŸãã ãã¶ããä»ã®ãŠã£ãžã§ããã¯ããã®userId
å
éšã§ç®¡çããStatefulWidget
ãªãã§ãããã å€åããã¯ä»£ããã«ããªã±ãŒããŠã£ãžã§ããããuserId
ãååŸããã§ãããã
ãã®æ§æã¯ãããã¯ãç¬èªã®ã©ã€ããµã€ã¯ã«ãæã€ç¬ç«ããState
ãªããžã§ã¯ãã®ãããªãã®ã§ããããšãæ確ã«ããå¿
èŠããããŸãã
è£è¶³ãšããŠãããã±ãŒãžãã¡ãŒã¹ãã¢ãããŒãã®1ã€ã®æ¬ ç¹ã¯ã次ã®ãšããã§ããããã±ãŒãžã®äœæè ã¯ãåé¡ã解決ããããã«ããã¯ã«äŸåããããã±ãŒãžãå ¬éããå¯èœæ§ãäœããªããŸãã
ããšãã°ããããã€ããŒãŠãŒã¶ãŒãçŽé¢ããäžè¬çãªåé¡ã®1ã€ã¯ããããã€ããŒã䜿çšãããªããªã£ããšãã«ãããã€ããŒã®ç¶æ
ãèªåçã«ç Žæ£ããããšããããšã§ãã
åé¡ã¯ããããã€ããŒãŠãŒã¶ãŒã¯ãåé·ãªConsumer(builder: ...)
/ Selector(builder:...)
æ§æãšã¯å¯Ÿç
§çã«ã context.watch
/ context.select
æ§æãéåžžã«æ°ã«å
¥ã£ãŠããããšã§ãã
ãããããã®çŽ æŽãããæ§æãšããã¯ãªãã§åè¿°ã®åé¡ã解決ããããšã¯ã§ããŸããïŒãŸãã¯https://github.com/flutter/flutter/pull/33213ãæåŠãããŸããïŒã
åé¡ã¯ïŒ
ãããã€ããŒã¯ããã®åé¡ã解決ããããã«flutter_hooks
ã«äŸåããããšã¯ã§ããŸããã
ãããã€ããŒã®äººæ°ãé«ããããããã¯ã«äŸåããã®ã¯ç¡çã§ãããã
ã ããçµå±ãç§ã¯ä»¥äžãéžã³ãŸããïŒ
context.watch
ã楜ãã人ã
ãæãæ§æãæäŸããŸããç§ã¯ããããã€ããŒããã倧å¹
ã«æ¹åãããŠãããšæãã®ã§ãç§ãæãã€ãããã®ã«éåžžã«æºè¶³ããŠããŸãïŒããã«ãããGeneratedWidgetsã¯ã³ã³ãã€ã«ã»ãŒãã«ãªããŸãïŒã
ããããããã«ãã©ãçãæ¹æ³ã¯ç§ã«æªãåŸå³ãæ®ããŸããã
ããã¯ããŒãžã§ã³ãšããããã£ããŒãžã§ã³ã®éãã¯ãåºæ¬çã«3ã€ãããŸãã
ãã€ã©ãŒãã¬ãŒãã³ãŒãã¯æ¬åœã«å€§ããããšã§ããïŒ ã€ãŸããããããã£ãç°¡åã«åå©çšã§ããããã«ãªããã³ãŒãããã¹ãŠ1ãæã«ãŸãšããããŸããã ãããã£ãŠãããã¯å®éã«ã¯åé·æ§ã®è°è«ã«ãããŸããã
è¯ã解決çã¯ããããç¥ã£ãŠããä»ã®ããã±ãŒãžã«äŸåãã¹ãã§ã¯ãªããšæããŸãã ãã¬ãŒã ã¯ãŒã¯å ã«ãããã©ããã¯é¢ä¿ãããŸããã ããã䜿ããªã人ã¯åé¡ã«ãªããªãã¯ãã§ãã ããã䜿çšããŠããªã人ãåé¡ã§ããå Žåãããã¯ãIMHOãAPIã®å±éºä¿¡å·ã§ãã
ã€ãŸããããããã£ãç°¡åã«åå©çšã§ããããã«ãªããã³ãŒãããã¹ãŠ1ãæã«ãŸãšããããŸããã
ã³ãŒãã1ã€ã®å Žæã«ãããããšãã£ãŠãåå©çšã§ããããã§ã¯ãããŸããã
çŸåš_ExampleState
å
ã«ããã³ãŒããå¥ã®ãŠã£ãžã§ããã§åå©çšããã»ã«ã³ããªãŠã£ãžã§ãããäœæããŠããã ããŸãããïŒ
ã²ãããå ããŠïŒãã®æ°ãããŠã£ãžã§ããã¯ã次ã®ããã«ãStateå
ã§userIDãå
éšçã«ç®¡çããå¿
èŠããããŸãã
class _WhateverState extends State with PropertyManager {
// may change over time after some setState calls
int userId;
}
ããã䜿çšããŠããªã人ãåé¡ã§ããå Žåãããã¯ãIMHOãAPIã®å±éºä¿¡å·ã§ãã
å ¬åŒã§ã¯ãªãããã«äœãã䜿çšããŠããªã人ã¯ãAPIãæªããšããæå³ã§ã¯ãããŸããã
ããã¯ç¶æããããã®äœåãªäœæ¥ã§ããããïŒããŒãžã§ã³ç®¡çãã©ã€ã»ã³ã¹ãæžäŸ¡ååŽãªã©ã®ããïŒãäŸåé¢ä¿ãè¿œå ããããªãããšã¯å®å
šã«æ£åœã§ãã
ç§ãèŠããŠããããšãããFlutterã«ã¯äŸåé¢ä¿ãã§ããã ãå°ãªãããå¿
èŠããããŸãã
çŸåšåºãåãå ¥ããããã»ãŒå ¬åŒã«ãªã£ãŠãããããã€ããŒèªäœã§ãããäŸåé¢ä¿ã®è¿œå ãé¿ããããã«ãçµã¿èŸŒã¿ã®ããããªãŠã£ãžã§ããã䜿çšããããšã奜ãããšèšãããã®ãç®ã«ããŸããã
çŸåš
_ExampleState
å ã«ããã³ãŒããå¥ã®ãŠã£ãžã§ããã§åå©çšããã»ã«ã³ããªãŠã£ãžã§ãããäœæããŠããã ããŸãããïŒ
åé¡ã®ã³ãŒãã¯ããŠã£ãžã§ããããuserIdãååŸãããããfetchUserã¡ãœããã«æž¡ãããšã«é¢ãããã®ã§ãã åããªããžã§ã¯ãå ã§ããŒã«ã«ã«å€æŽãããuserIdã管çããããã®ã³ãŒãã¯ç°ãªããŸãã ããã¯å€§äžå€«ã®ããã§ããïŒ ããã§ã©ã®ãããªåé¡ã解決ããããšããŠããã®ãããããããŸããã
èšé²ã®ããã«ãç§ã¯ããªãã説æããããšãããããã«ããããã£ã䜿çšããŸãããããã¯ã¡ããã©æ¬¡ã®ããã«ãªããŸãïŒ
class Example extends StatefulWidget {
Example({ Key key }): super(key: key);
<strong i="10">@override</strong>
_ExampleState createState() => _ExampleState();
}
class _ExampleState extends State<Example> with PropertyManager {
int _userId;
Future<User> _future;
void _setUserId(int newId) {
if (newId == _userId)
return;
setState(() {
_future = fetchUser(_userId);
});
}
// ...code that uses _setUserId...
<strong i="11">@override</strong>
Widget build(BuildContext context) {
return FutureBuilder<User>(
future: _future.value,
builder: (context, snapshot) {
if (!snapshot.hasData) return Text('loading');
return Text(snapshot.data.name);
},
);
}
}
å ¬åŒã§ã¯ãªãããã«äœãã䜿çšããŠããªã人ã¯ãAPIãæªããšããæå³ã§ã¯ãããŸããã
åæããŸããã
人ã
ãæªããã®ã䜿çšããªããšããäºå®ã¯ãAPIãæªãããšãæå³ããŸãã ãããã±ãŒãžã®äœæè
ã¯ãåé¡ã解決ããããã«ããã¯ã«äŸåããããã±ãŒãžãå
¬éããå¯èœæ§ãäœãããšèšããšããããã¯ããã¯ãããªãã«åœ¹ç«ã€ããã«ããã䜿çšããŠããä»ã®äººã
ã«äŸåããŠããããšã瀺ããŸãã åªããAPIã§ããIMHOã¯ãä»ã®èª°ããããæ¡çšããªããŠãæªããªãããšã¯ãããŸããã ä»ã®èª°ãããã«ã€ããŠç¥ããªããŠããããã¯æã¡ããããã¯ãã§ãã ããšãã°ãäžèšã®Property
äŸã¯ãããèªäœã圹ç«ã€ä»ã®ããã±ãŒãžã«äŸåããŠããŸããã
çŸåšåºãåãå ¥ããããã»ãŒå ¬åŒã«ãªã£ãŠãããããã€ããŒèªäœã§ãããäŸåé¢ä¿ã®è¿œå ãé¿ããããã«ãçµã¿èŸŒã¿ã®ããããªãŠã£ãžã§ããã䜿çšããããšã奜ãããšèšãããã®ãç®ã«ããŸããã
AliExpressWidgetã®äœ¿çšã奜ã人ã®äœãåé¡ã«ãªã£ãŠããŸããïŒ ç§ã¯äººã ã«è§£æ±ºçã匷å¶ããããããŸããã 圌ãã¯åœŒãã䜿ããããã®ã䜿ãã¹ãã§ãã ããªãã¯æåéãåé¡ã®ãªãããšã説æããŠããŸãã ããªããŒãžãŠã£ãžã§ããã®äœ¿çšã奜ã人ã ãžã®è§£æ±ºçã¯ãéªéã«ãªããªãããã«ããŠãç¶æ¿ãŠã£ãžã§ããã䜿çšã§ããããã«ããããšã§ãã
ã åªããAPIã§ããIMHOã¯ãä»ã®èª°ããããæ¡çšããªããŠãæªããªãããšã¯ãããŸããã ä»ã®èª°ãããã«ã€ããŠç¥ããªããŠããããã¯æã¡ããããã¯ãã§ãã ããšãã°ãäžèšã®ããããã£ã®äŸã¯ãããèªäœã圹ç«ã€ããã«ããã䜿çšããä»ã®ããã±ãŒãžã«äŸåããŠããŸããã
誀解ããããŸãã
åé¡ã¯ãäžè¬çã«ããã¯ã䜿çšããŠããªã人ã
ã«é¢ãããã®ã§ã¯ãããŸããã
ããã¯ã¯å
¬åŒã§ã¯ãªãã®ã«å¯Ÿãããããã€ããŒã¯å
¬åŒã§ã¯ãªãããããããã€ããŒãããã¯ã䜿çšããŠåé¡ãä¿®æ£ã§ããªããšããããšã§ãã
åããªããžã§ã¯ãå ã§ããŒã«ã«ã«å€æŽãããuserIdã管çããããã®ã³ãŒãã¯ç°ãªããŸãã ããã¯å€§äžå€«ã®ããã§ããïŒ ããã§ã©ã®ãããªåé¡ã解決ããããšããŠããã®ãããããããŸããã
èšé²ã®ããã«ãç§ã¯ããªãã説æããããšãããããã«ããããã£ã䜿çšããŸãããããã¯ã¡ããã©æ¬¡ã®ããã«ãªããŸãïŒ
ããã¯è³ªåã«çããŸããã ç¹ã«ãããã¯ãšããããã£ã®éã§ã³ãŒãã®åå©çšæ§ãæ¯èŒããããã«äŸé ŒããŸããã
ããã¯ã䜿çšãããšã FetchUser
åå©çšã§ããŸãã
class _WhateverState extends State with PropertyManager {
// may change over time after some setState calls
int userId;
Widget build(context) {
final user = use(FetchUser(userId));
}
}
ããã¯ã䜿çšãããšã
FetchUser
åå©çšã§ããŸãã
ãªããããæãŸããã®ãããããŸããã FetchUser
ã¯èå³æ·±ãã³ãŒãã¯ãªããããã¯ããfetchUser
é¢æ°ãžã®ã¢ããã¿ãŒã«ãããŸããã fetchUser
çŽæ¥é»è©±ããŠã¿ãŸãããïŒ åå©çšããŠããã³ãŒãã¯èå³æ·±ãã³ãŒãã§ã¯ãããŸããã
ããã¯ã¯å ¬åŒã§ã¯ãªãã®ã«å¯Ÿãããããã€ããŒã¯å ¬åŒã§ã¯ãªãããããããã€ããŒãããã¯ã䜿çšããŠåé¡ãä¿®æ£ã§ããªããšããããšã§ãã
IMHOã¯ãã³ãŒãã®åå©çšã®åé¡ã«å¯Ÿããåªãããœãªã¥ãŒã·ã§ã³ããããã€ããŒãæ¡çšããå¿ èŠã¯ãŸã£ãããããŸããã ãããã¯å®å šã«çŽäº€ããæŠå¿µã«ãªããŸãã ããã¯ãFlutterã¹ã¿ã€ã«ã¬ã€ãããè€éåãé¿ããããšããèŠåºãã®äžã§è©±ããŠããããšã§ãã
ãªããããæãŸããã®ãããããŸããã FetchUserã«ã¯èå³æ·±ãã³ãŒãã¯ãããŸãããããã¯ãããã¯ããfetchUseré¢æ°ãžã®åãªãã¢ããã¿ãŒã§ãã fetchUserãçŽæ¥åŒã³åºããªãã®ã¯ãªãã§ããïŒ åå©çšããŠããã³ãŒãã¯èå³æ·±ãã³ãŒãã§ã¯ãããŸããã
ããã¯åé¡ã§ã¯ãããŸããã ã³ãŒãã®åå©çšæ§ãå®èšŒããããšããŠããŸãã fetchUser
ã¯ãããšãã°ChangeNotifier.addListener
ãªã©ãäœã§ãããŸããŸããã
fetchUser
ã«äŸåãããæé»çãªããŒã¿ãã§ãããè¡ãããã®APIãæäŸããã ãã®ä»£æ¿å®è£
ãäœæã§ããŸãã
int userId;
Widget build(context) {
AsyncSnapshot<User> user = use(ImplicitFetcher<User>(userId, fetch: () => fetchUser(userId));
}
IMHOã¯ãã³ãŒãã®åå©çšã®åé¡ã«å¯Ÿããåªãããœãªã¥ãŒã·ã§ã³ããããã€ããŒãæ¡çšããå¿ èŠã¯ãŸã£ãããããŸããã ãããã¯å®å šã«çŽäº€ããæŠå¿µã«ãªããŸãã ããã¯ãFlutterã¹ã¿ã€ã«ã¬ã€ãããè€éåãé¿ããããšããèŠåºãã®äžã§è©±ããŠããããšã§ãã
ã ããç§ã¯ããã¯ãåå§çã ãšèšã£ãã®ã§ã
æ¯å©ãšããŠïŒ
package:animations
ã¯Animation
äŸåããŸãã ããããããã¯ã³ã¢ããªããã£ãã§ãããããããã¯åé¡ã§ã¯ãããŸããã
代ããã«package:animations
ãã³ãã¥ããã£ã«ãã£ãŠç¶æãããŠããAnimation
ãã©ãŒã¯ã䜿çšããŠããå Žåã¯å¥ã®åé¡ã«ãªããŸã
@escamoteurããããŸãããããŠã£ãžã§ããã®åäœãæ ¹æ¬çã«å€ããããšãææ¡ããŠããŸããïŒ ãããšããç¹å®ã®æ°ããèœåãããã¹ãã ãšææ¡ããŠããŸããïŒ ã³ã¢ãã¬ãŒã ã¯ãŒã¯ãå€æŽããã«ããã¯ãäžèšã®ããããã£ææ¡ã®ãããªããšãã©ã®ããã«å¯èœã§ããããèãããšãå®éã«äœãå€æŽããããã¯ç§ã«ã¯ããããŸããã
@Hixieç§ã®ãã€ã³ãã¯ãããã¯ãããã«äººæ°ã«ãªã£ãå ŽåãFlutterã³ãŒããã©ã®ããã«èŠããã©ã®ããã«åäœããããå
±éã«ç解ã§ããããã«ãããã¯ããã¬ãŒã ã¯ãŒã¯ã«å«ããŠãã¹ãŠã®äººã«æããããšã
ç§ã¯ããªãã®æžå¿µãéåžžã«å
±æããŸãããå察åŽã§ã¯ããã¯ä»ãã®ãŠã£ãžã§ããã¯æ¬åœã«ãšã¬ã¬ã³ãã«èŠããŸãã
以åã®ããã«ç©äºãè¡ãããšãçŠæ¢ããããšã¯ãããŸããã
以åã®ããã«ç©äºãè¡ãããšãçŠæ¢ããããšã¯ãããŸããã
FlutterããŒã ãããã©ãã¿ãŒããã¯ããå§ãããŸããã以åãšåãããã«ã§ããããšèšãã®ã¯è¯ãèãã§ã¯ãªããšæããŸãã人ã ã¯ããã«ã€ããŠæ··ä¹±ããã§ãããã ãŸããFlutterããŒã ãå°æ¥ããã¯ãæšå¥šããå Žåã¯ãäŸãšããŠå®éã®Flutterã³ãŒãã®å ¬éãåæ¢ããå¿ èŠããããŸãã
人ã ã¯åžžã«ç©äºãè¡ããå ¬åŒã®æ¹æ³ãã«åŸããŸãããããŠç§ã¯ããã«ãã©ãã¿ãŒã䜿çšãã2ã€ã®å ¬åŒã®æ¹æ³ãããã¹ãã§ã¯ãªããšæããŸãã
ããã¯åé¡ã§ã¯ãããŸããã ã³ãŒãã®åå©çšæ§ãå®èšŒããããšããŠããŸãã
fetchUser
ã¯ãããšãã°ChangeNotifier.addListener
ãªã©ãäœã§ãããŸããŸããã
ãã¡ããã ãããé¢æ°ãé©ããŠããããšã§ããã³ãŒããæœè±¡åããããšã§ãã ããããç§ãã¡ã¯ãã§ã«æ©èœãæã£ãŠããŸãã äžèšã®ããããã£ã³ãŒããšäžèšã®_setUserIdã³ãŒãã¯ããã¬ãŒã ã¯ãŒã¯ããã®ç¹å¥ãªæ¯æŽãå¿ èŠãšããã«ããããã®é¢æ°ãåŒã³åºããã¹ãŠã®ã³ãŒãã1ãæã«ãŸãšããããšãã§ããããšã瀺ããŠããŸãã ãããã®é¢æ°ãžã®åŒã³åºããã©ããããããã«ããã¯ãå¿ èŠãªã®ã¯ãªãã§ããïŒ
IMHOã¯ãã³ãŒãã®åå©çšã®åé¡ã«å¯Ÿããåªãããœãªã¥ãŒã·ã§ã³ããããã€ããŒãæ¡çšããå¿ èŠã¯ãŸã£ãããããŸããã ãããã¯å®å šã«çŽäº€ããæŠå¿µã«ãªããŸãã ããã¯ãFlutterã¹ã¿ã€ã«ã¬ã€ãããè€éåãé¿ããããšããèŠåºãã®äžã§è©±ããŠããããšã§ãã
ã ããç§ã¯ããã¯ãåå§çã ãšèšã£ãã®ã§ã
ãããã¯äŸ¿å©ã§ãããåå§çã§ã¯ãããŸããã ããããåå§çã§ããå Žåããåé¡ã¯äœã§ããããšãã質åã«çããã®ã¯ã¯ããã«ç°¡åã§ãã ããªãã¯ããããç§ãããããããšã§ãããç§ã¯ãããããããšãã§ããªãããšèšãã§ãããã
æ¯å©ãšããŠïŒ
package:animations
ã¯Animation
äŸåããŸãã ããããããã¯ã³ã¢ããªããã£ãã§ãããããããã¯åé¡ã§ã¯ãããŸããã
代ããã«package:animations
ãã³ãã¥ããã£ã«ãã£ãŠç¶æãããŠããAnimation
ãã©ãŒã¯ã䜿çšããŠããå Žåã¯å¥ã®åé¡ã«ãªããŸã
Animationã¯ã©ã¹éå±€ã¯ãåºæ¬çãªããšãè¡ããŸããããã¯ããã£ãã«ãŒãšãããããå¶åŸ¡ããŠãµãã¹ã¯ã©ã€ãããæ¹æ³ãå°å ¥ããŸãã Animationã¯ã©ã¹éå±€ããªãå Žåãã¢ãã¡ãŒã·ã§ã³ãå®è¡ããã«ã¯ãAnimationã¯ã©ã¹éå±€ã®ãããªãã®ãçºæããå¿ èŠããããŸãã ïŒçæ³çã«ã¯ãã£ãšè¯ããã®ã§ããããã¯ç§ãã¡ã®æé«ã®ä»äºã§ã¯ãããŸãããïŒããã¯ã¯æ°ããåºæ¬çãªæ©èœãå°å ¥ããŠããŸããã åãã³ãŒããå¥ã®æ¹æ³ã§èšè¿°ããæ¹æ³ãæäŸããã ãã§ãã ãã®ã³ãŒãã¯åçŽã§ããããããã§ãªãå Žåãšã¯ç°ãªãå æ°å解ãããŠããå¯èœæ§ããããŸãããããã¯ããªããã£ãã§ã¯ãããŸããã ããã¯ã䜿çšããã³ãŒããšåãããšãè¡ãã³ãŒããäœæããããã«ãããã¯ã®ãããªãã¬ãŒã ã¯ãŒã¯ã¯å¿ èŠãããŸããã
åºæ¬çã«ããã®åé¡ã§èª¬æãããŠããåé¡ã¯ããã¬ãŒã ã¯ãŒã¯ã§ä¿®æ£ããå¿ èŠããããã®ã§ã¯ãªããšæããŸãã ããã«å¯ŸåŠããæ¹æ³ã«ã€ããŠã¯ã人ã«ãã£ãŠããŒãºã倧ããç°ãªããŸãã ãããä¿®æ£ããæ¹æ³ã¯ãããããããŸãããã®ãã°ã§ã¯ãã§ã«ããã€ã説æããŸããã ããã€ãã®æ¹æ³ã¯éåžžã«åçŽã§ãæ°åã§èšè¿°ã§ããããã解決ãããã»ã©é£ããåé¡ã§ã¯ãªãããœãªã¥ãŒã·ã§ã³ãææããã³ç¶æããããã®äŸ¡å€ããããŸãã ããããã®ææ¡ã«ã¯é·æãšçæããããŸãã 匱ç¹ã¯ããããã®å Žåãã誰ãããããã䜿çšããã®ã劚ãããã®ã§ãã åé¡ãä¿®æ£ããå¿ èŠãããããšã«èª°ããåæããŠããããšããã¯ã£ããããŠããŸããã
ããã¯_are_ããªããã£ã
ããã¯ãã³ããã®ã¹ã¬ããã§ãïŒ https ïŒ
ããå
·äœçã«ã¯ã flutter_hooks
ãåçãªç¶æ
ããã¯ã¹ã€ã³ãšèããããšãã§ããŸãã
ããããåå§çã§ããå Žåããåé¡ã¯äœã§ããããšãã質åã«çããã®ã¯ã¯ããã«ç°¡åã§ãã ããªãã¯ããããç§ãããããããšã§ãããç§ã¯ãããããããšãã§ããªãããšèšãã§ãããã
ããã¯OPã«ãããŸãïŒ
ç¶æ
ããžãã¯ãåå©çšããããšã¯å°é£ã§ãã æçµçã«è€éã§æ·±ããã¹ãããããã«ãã¡ãœããã«ãªãããè€æ°ã®ãŠã£ãžã§ããéã§ããžãã¯ãã³ããŒããŠè²Œãä»ããå¿
èŠããããŸãã
ããã¯ã¹ã€ã³ãé¢æ°ãä»ããŠãã®ãããªããžãã¯ãåå©çšããããšã¯ã§ããŸããã
ãã®ã³ãŒãã¯åçŽã§ããããããã§ãªãå Žåãšã¯ç°ãªãå æ°å解ãããŠããå¯èœæ§ããããŸãããããã¯ããªããã£ãã§ã¯ãããŸããã ããã¯ã䜿çšããã³ãŒããšåãããšãè¡ãã³ãŒããäœæããããã«ãããã¯ã®ãããªãã¬ãŒã ã¯ãŒã¯ã¯å¿ èŠãããŸããã
ããã°ã©ã ãæžãã®ã«ã¯ã©ã¹ã¯å¿
èŠãããŸããã ãã ããã¯ã©ã¹ã䜿çšãããšãã³ãŒããæ§é åããæå³ã®ããæ¹æ³ã§å æ°å解ããããšãã§ããŸãã
ãããŠãã¯ã©ã¹ã¯ããªããã£ãã§ãã
ããªããã£ãã§ãããããã¯ã¹ã€ã³ã§ãåãã§ã
ããã¯ãåãã§ãã
ãããã®é¢æ°ãžã®åŒã³åºããã©ããããããã«ããã¯ãå¿ èŠãªã®ã¯ãªãã§ããïŒ
ãã®ããžãã¯ã_one_ã®å Žæã§ã¯ãªãã_two_ã®å Žæã§åŒã³åºãå¿ èŠãããå Žåã«åããŠã
ããã¯ã¹ã€ã³ãé¢æ°ãä»ããŠãã®ãããªããžãã¯ãåå©çšããããšã¯ã§ããŸããã
å ·äœçãªäŸãæããŠãã ããã ãããŸã§ã®ãšãããç§ãã¡ãç 究ãããã¹ãŠã®äŸã¯ãããã¯ã®ãªãåçŽãªãã®ã§ãã
ãããŸã§ã®ãšããããã®ã¹ã¬ããã§ã¯ãç¶æ ããžãã¯ã解決ããŠåå©çšããã³æ§æããã®ã容æã«ãã@rrousselGitããã¯ä»¥å€ã®è§£æ±ºçãèŠãããšããããŸããã
確ãã«ãç§ã¯æè¿ããŒãããã©ãã¿ãŒãããŸãè¡ã£ãŠããªãã®ã§ãäžèšã®ããããã£ãœãªã¥ãŒã·ã§ã³ã³ãŒããµã³ãã«ã«äœããæ¬ ããŠããå¯èœæ§ããããŸããã解決çã¯ãããŸããïŒ åå©çšã®ä»£ããã«ã³ããŒããŒã¹ããå¿
èŠãšããªãä»æ¥ã®ãªãã·ã§ã³ã¯äœã§ããïŒ
@rrousselGitã®è³ªåã«å¯Ÿããçãã¯äœã§ããïŒ
çŸåš_ExampleStateå ã«ããã³ãŒããå¥ã®ãŠã£ãžã§ããã§åå©çšããã»ã«ã³ããªãŠã£ãžã§ãããäœæããŠããã ããŸãããïŒ
ã²ãããå ããŠïŒãã®æ°ãããŠã£ãžã§ããã¯ããã®ç¶æ ã®å éšã§ãã®ãŠãŒã¶ãŒIDã管çããå¿ èŠããããŸã
äžèšã®ããããã£ãœãªã¥ãŒã·ã§ã³ã§ãã®ãããªç°¡åãªç¶æ
ããžãã¯ãåå©çšã§ããªãå Žåãä»ã®ãªãã·ã§ã³ã¯äœã§ããïŒ
çãã¯ããã©ãã¿ãŒã§ç°¡åã«åå©çšã§ããããã«ããã¹ãã§ã¯ãªããšããããšã§ããïŒ ããã¯ãŸã£ããåé¡ãããŸããããå°ãæ²ããç§èŠã§ãã
ãšããã§ãSwiftUIã¯æ°ãã/ä»ã®åºæ¿çãªæ¹æ³ã§ãããè¡ããŸããïŒ ãããšããåãç¶æ ããžãã¯ã®åå©çšæ§ãæ¬ ããŠããã®ã§ããããã ç§èªèº«ã¯swiftuiããŸã£ãã䜿çšããŠããŸããã å€åããã¯ããŸãã«ãç°ãªã£ãŠããŸããïŒ
åºæ¬çã«ãã¹ãŠã®ãã«ããŒã çŸæç¹ã§ã¯ããã«ããŒãç¶æ
ãåå©çšããå¯äžã®æ¹æ³ã§ãã
ããã¯ã«ããããã«ããŒã¯èªã¿ããããäœæãããããªããŸã
ããã¯ãç§ãŸãã¯äžéšã®ã¯ã©ã€ã¢ã³ããå æããŸããŸãªãããžã§ã¯ãã®ããã«äœæããã«ã¹ã¿ã ããã¯ã®ã³ã¬ã¯ã·ã§ã³ã§ãã
useQuery
âããã¯åã«äžããImplicitFetcher
ããã¯ãšåçã§ããã代ããã«GraphQLã¯ãšãªãäœæããŸããuseOnResume
ã¯ã AppLifecycleState.resumed
ã«å¯ŸããŠã«ã¹ã¿ã ã¢ã¯ã·ã§ã³ãå®è¡ããããã®ã³ãŒã«ããã¯ãæäŸããŸããuseDebouncedListener
ã¯ããªã¹ããã«ïŒéåžžã¯TextFieldãŸãã¯ScrollControllerïŒããªãã¹ã³ããŸããããªã¹ããŒã§ãããŠã³ã¹ããŸãuseAppLinkService
ããã«ããããŠã£ãžã§ããã¯AppLifecycleState.resumed
ãšåæ§ã®ã«ã¹ã¿ã ã€ãã³ãã§ããã€ãã®ããžãã¯ãå®è¡ã§ããŸãããããžãã¹ã«ãŒã«ããããŸãuseShrinkUIForKeyboard
ã¯ãããŒããŒãã®å€èŠ³ãã¹ã ãŒãºã«åŠçããŸãã UIãäžéšã®ããã£ã³ã°ã«é©å¿ããå¿
èŠããããã©ããã瀺ãããŒã«å€ãè¿ããŸãïŒããã¯focusNodeã®ãªãã¹ã³ã«åºã¥ããŠããŸãïŒuseFilter
ã useDebouncedListener
ãšuseState
ïŒåäžã®ããããã£ã宣èšããããªããã£ãããã¯ïŒãçµã¿åãããŠãæ€çŽ¢ããŒã®ãã£ã«ã¿ãŒãå
¬éããŸããuseImplicitlyAnimated<Int/Double/Color/...>
âããã¯ãšããŠã®TweenAnimationBuilder
çžåœã¢ããªã¯ãŸããããŸããŸãªããžãã¯ã«å€ãã®äœã¬ãã«ã®ããã¯ã䜿çšããŸãã
ããšãã°ã次ã®ä»£ããã«ïŒ
Whatever whatever;
initState() {
whatever = doSomething(widget.id);
}
didUpdateWidget(oldWidget) {
if (oldWidget.id != widget.id)
whatever = doSomething(widget.id);
}
圌ãã¯ããŸãïŒ
Widget build(context) {
final whatever = useUnaryEvent<Whatever, int>(widget.id, (int id) => doSomething(id));
}
ããã«ããã initState
/ didUpdateWidget
/ didChangeDependencies
éã®éè€ãåé¿ãããŸãã
ãŸãã Riverpodã®useProvider
倧éã«äœ¿çšããŸããããã§ãªãå Žåã¯ã StreamBuilder
/ ValueListenableBuilder
éèŠãªã®ã¯ããŠã£ãžã§ãããã1ã€ã®ããã¯ãã䜿çšããããšã¯ãã£ãã«ãªããšããããšã§ãã
ããšãã°ããŠã£ãžã§ããã¯
class ChatScreen extends HookWidget {
const ChatScreen({Key key}) : super(key: key);
<strong i="13">@override</strong>
Widget build(BuildContext context) {
final filter = useFilter(debounceDuration: const Duration(seconds: 2));
final userId = useProvider(authProvider).userId;
final chatId = useProvider(selectedChatProvider);
final chat = useQuery(ChatQuery(userId: userId, chatId: chatId, filter: filter.value));
return Column(
children: [
Searchbar(onChanged: (value) => filter.value = value),
Expanded(
child: ChatList(chat: chat),
),
],
);
}
}
ç°¡æœã§éåžžã«èªã¿ãããã§ãïŒãã¡ãããAPIã®åºæ¬çãªç¥èãããããšãåæãšããŠããŸãïŒã
ãã¹ãŠã®ããžãã¯ã¯äžããäžã«èªã¿åãããšãã§ããŸããã³ãŒããç解ããããã«ã¡ãœããéããžã£ã³ãããå¿
èŠã¯ãããŸããã
ãããŠãããã§äœ¿çšããããã¹ãŠã®ããã¯ã¯ãã³ãŒãããŒã¹ã®è€æ°ã®å Žæã§åå©çšãããŸã
ããã¯ãªãã§ãŸã£ããåãããšãè¡ããšãããã次ã®ããã«ãªããŸãã
class ChatScreen extends StatefulWidget {
const ChatScreen({Key key}) : super(key: key);
<strong i="20">@override</strong>
_ChatScreenState createState() => _ChatScreenState();
}
class _ChatScreenState extends State<ChatScreen> {
String filter;
Timer timer;
<strong i="21">@override</strong>
void dispose() {
timer?.cancel();
super.dispose();
}
<strong i="22">@override</strong>
Widget build(BuildContext context) {
return Consumer<Auth>(
provider: authProvider,
builder: (context, auth, child) {
return Consumer<int>(
provider: selectedChatProvider,
builder: (context, chatId, child) {
return GraphQLBuilder<Chat>(
query: ChatQuery(
userId: auth.userId,
chatId: chatId,
filter: filter.value,
),
builder: (context, chat, child) {
return Column(
children: [
Searchbar(
onChanged: (value) {
timer?.cancel();
timer = Timer(const Duration(seconds: 2), () {
filter = value;
});
},
),
Expanded(
child: ChatList(chat: chat),
),
],
);
},
);
},
);
},
);
}
}
ããã¯ããªãèªã¿ã«ãããªããŸãã
FilterBuilder
ãäœæãããš12ã¬ãã«ã«ãªããŸãtimer
ããã£ã³ã»ã«ããã®ãå¿ããå¯èœæ§ããããŸãbuild
ã¡ãœããã®ååã¯èªè
ã«ã¯åœ¹ã«ç«ã¡ãŸããã ãã«ããŒã¯éèŠãªããšããç§ãã¡ã®æ°ãããããŸãç§èªèº«flutter_hooks
ãŠãŒã¶ãŒãšããŠãç§ã¯èªåã®æèŠãæçš¿ããŸãã ããã¯ã䜿çšããåã¯ãFlutterã«æºè¶³ããŠããŸããã ç§ã¯ãã®ãããªãã®ã®å¿
èŠæ§ãèŠãŸããã§ããã ããã«ã€ããŠèªãã§ãããã«ã€ããŠã®ãŠãŒãã¥ãŒããããªãèŠãåŸãç§ã¯ãŸã 確信ããŠããŸããã§ãããããã¯ã¯ãŒã«ã«èŠããŸããããããç§ã¯ãããæ¬åœã«åæ©ã¥ããããã«ããã€ãã®ç·Žç¿ãŸãã¯äŸãå¿
èŠã§ããã ããããããããç§ã¯äœãã«æ°ã¥ããŸããã ç§ã¯ã¹ããŒããã«ãªãŠã£ãžã§ããã絶察ã«é¿ããŠããŸããããã€ã©ãŒãã¬ãŒããããããå«ãŸããŠããŠãã¯ã©ã¹ãã¹ãããããŠç©äºãèŠã€ããããšããŠããŸããã ãã®ãããäžæçãªç¶æ
ã®ã»ãšãã©ããã¢ããªã®æ®ãã®ç¶æ
ãšãšãã«ç¶æ
管çãœãªã¥ãŒã·ã§ã³ã«ç§»è¡ããã¹ããŒãã¬ã¹ãŠã£ãžã§ããã䜿çšããŠããŸããã ãã ããããã«ããã Navigator
ããŸãã¯InheritedWidget
s / Providers
ã«ã¢ã¯ã»ã¹ããããã®BuildContext
ååŸã«äŸåãããããããžãã¹ããžãã¯ã¯Flutterã«ãã°ããäŸåããŸããæšã ãããè¯ãç¶æ
管çã¢ãããŒãã§ãããšã¯èšããªãããããã§ã¯ãªãã£ãããšãç§ã¯ç¥ã£ãŠããã ããããUIã®ç¶æ
管çã«ã€ããŠå¿é
ããå¿
èŠããªãããã«ãã§ããããšã¯äœã§ãããŸããã
ãã°ããã®éããã¯ã䜿çšããåŸãç§ã¯èªåèªèº«ãã¯ããã«çç£çã§ãFlutterã䜿çšããŠã¯ããã«å¹žãã§ãããã¢ããªã®ç¶æ ã§ã¯ãªããäžæçãªç¶æ ãïŒUIãšãšãã«ïŒé©åãªå Žæã«é 眮ããŸããã
ç§ã«ãšã£ãŠãããã¯äžæçãªç¶æ
/ã³ã³ãããŒã©ãŒã®ã¬ããŒãžã³ã¬ã¯ã¿ãŒã®ãããªãã®ã§ãã UIã§ãã¹ãŠã®ãµãã¹ã¯ãªãã·ã§ã³ãç Žæ£ããããšãèŠããŠããå¿
èŠã¯ãããŸãããããããflutter_hooks
ãç§ã®ããã«è¡ãããšã§ãããšããäºå®ããŸã éåžžã«æèããŠããŸãã ãŸããã³ãŒãã®ä¿å®ãšãªãã¡ã¯ã¿ãªã³ã°ãéåžžã«ç°¡åã«ãªããŸãã ç§ã®å€§åŠé¢ã®ç 究ãšæ¥œãã¿ã®ããã«ãéå»1幎éã«æ倧10åã®ã¢ããªãæžããããšãã話ããŠããŸãã
ä»ã®äººãšåãããã«ãFlutterSDKèªäœã«ãããå«ããããšã®äž»ãªåæ©ã¯æ£ç¢ºã«ã¯ããããŸããã ããããããã«ãã®äž»é¡ã«é¢ãã2ã€ã®èãããããŸãã
ãšãã©ããåæå/ç Žæ£ããå¿
èŠã®ããã³ã³ãããŒã©ãŒãå«ãããã±ãŒãžã䜿ããããããããã«ããã¯ãäœæããŸãã ïŒããšãã°ã golden_layout
ããŸãã¯zefyr
ïŒã flutter_hooks
ã䜿çšããŠããä»ã®ãŠãŒã¶ãŒã¯ããã®ãããªããã±ãŒãžã®æ©æµãåãããšæããŸãã ãã ããæåéã1ã3åã®é¢æ°ãå«ãããã±ãŒãžãå
¬éããããšãæ£åœåããããšã¯ã§ããªãããã§ãã å¥ã®æ¹æ³ã¯ãç§ã䜿çšããããŸããŸãªããã±ãŒãžã®ããã¯ãããããå«ããããã³ã·ã³ã¯ããã±ãŒãžãäœæããããšã§ãããã®åŸãgitäŸåé¢ä¿ã䜿çšã§ããŸããããããã®ä»ã®ããã±ãŒãž+ flutter_hooksã䜿çšãã人ã¯èª°ã§ãç§ã®gitã«äŸåããå¿
èŠããããŸããå©çãåŸãããã«ïŒããã¯çºèŠããã«ãããæ°ã«ããªãããã±ãŒãžãžã®äŸåé¢ä¿ãå«ãŸããŠããå¯èœæ§ããããŸãïŒããŸãã¯3ã€ã®é¢æ°ãå«ãããã±ãŒãžã«äŸåããããã¬ãŒãã³ã·ã³ã¯ããã±ãŒãžãpub.devã«å
¬éããŸãã ãã¹ãŠã®ã¢ã€ãã¢ã¯ã°ãããŠããããã§ãããŸãçºèŠã§ããŸããã flutter_hooks
ã®ä»ã®ãŠãŒã¶ãŒã¯ããããã®é¢æ°ãç°¡åã«ã³ããŒããŠã³ãŒãã«è²Œãä»ããããããžãã¯èªäœãç解ããããšãããã§ããŸãããã³ãŒã/ããã±ãŒãžãå
±æãããšããç¹ãå®å
šã«èŠéããŠããŸãã é¢æ°ã¯ãäžéšã®ãæ¡åŒµããã±ãŒãžãã§ã¯ãªããå
ã®ããã±ãŒãžã«å
¥ããæ¹ãã¯ããã«åªããŠããŸãã flutter_hooks
ããã¬ãŒã ã¯ãŒã¯ã®äžéšã§ããå ŽåããŸãã¯characters
ããã«ãã¬ãŒã ã¯ãŒã¯ãã䜿çšãŸãã¯ãšã¯ã¹ããŒããããããã±ãŒãžã§ããããå Žåãå
ã®ããã±ãŒãžã®äœæè
ã¯åçŽãªããã¯ã®ãã«ãªã¯ãšã¹ããåãå
¥ããå¯èœæ§ãã¯ããã«é«ããªããŸããé¢æ°ã§ããã1ã3åã®é¢æ°ããã±ãŒãžãæ··ä¹±ããããšã¯ãããŸããã
flutter_hooks
ãFlutterã«æ¡çšãããŠããªãå Žåãpub.devã®æ€çŽ¢çµæã1ã3åã®é¢æ°ããã±ãŒãžã§ä¹±éã«ãªããšäºæ³ãããŸãã ãããã®ããã±ãŒãžãéåžžã«å°ãããšããäºå®ã¯ããããããªããã£ãã§ãããšãã@rrousselGitã«æ¬åœã«åæããŸãã flutter_hooks
ãªããžããªã®1228ã®æãã @ rrousselGitã«ãã£ãŠèšåãããåé¡ã解決ããŠããããšã瀺ããŠããªãå Žåãç§ã¯äœã§ãããããããŸããã
Flutterãªããžããªãžã®è²¢ç®ã«ã€ããŠã®YouTubeãããªãèŠãŠããã®ã¯ãç§ãäœãã§ããããç¥ããããšæã£ãŠããããã§ãã ç§ãèŠãŠãããšãæ°ããããããã£ã«è¿œå ããããããªãäœæãã人ã¯ããªãç°¡åã§ããã dispose
ã didUpdateWidget
ãããã³debugFillProperties
ã®æŽæ°ã®é¢åãèŠãã®ãã»ãšãã©å¿ããŠããŸããã ã¹ããŒããã«ãŠã£ãžã§ããã®ãã¹ãŠã®è€éããããäžåºŠèŠãŠãäœããèŠéããããããšã§ãç§ã¯åã³ããããä¿¡çšã§ããªããªããã¡ã€ã³ã®Flutterãªããžããªã«è²¢ç®ããããšã«ããã»ã©è奮ããªããªããŸããã ãããå®å
šã«ç§ãæããšã©ãŸããããšã¯èšããŸããããç§ã¯ãŸã è²¢ç®ããããšã«èå³ããããŸãããç¶æãšã¬ãã¥ãŒãé£ããå®åã³ãŒããäœæããããã«æããŸãã ããã¯ãã³ãŒããæžãããšã®è€éãã§ã¯ãªããã³ãŒããèªãã§ãããªããé©åã«åŠåããäžæçãªç¶æ
ãåŠçããããšã確èªããããšã®è€éãã§ãã
é·ãé察å¿ããŠç³ãèš³ãããŸããã§ããããç§ã¯æã
ãã®åé¡ãæ€èšããŠãããFlutterããŒã ããã®åçã«å€å°æžæã£ãŠããŸãã äž¡æ¹ã®æ¹æ³ã§ã¢ããªãè©ŠããŠã¿ãŠãéããèªåã§ç¢ºèªããã®ã«æéãããã£ãŠããªãããã§ãã è¿œå ã®äŸåé¢ä¿ãç¶æãããããã¬ãŒã ã¯ãŒã¯ã«é床ã«çµ±åãããããããªããšããé¡æãç解ããŠããŸãã ãã ãã flutter_hook
ãã¬ãŒã ã¯ãŒã¯ã®ã³ã¢éšåã¯ãååã«ææžåããã500è¡ã®ã³ãŒãã®ã¿ã§ãã ç¹°ãè¿ãã«ãªããŸããããããäŒè©±ã«æ£æ¥ããŠããå Žåã¯ç³ãèš³ãããŸããã2ã»ã³ããäžããŠçºèšããããšã§èª°ããæãããªãããšãé¡ã£ãŠããŸãã @rrousselGitãéåžžã«è¯ãç¹ã瀺ããŠãããæ確ã§ãããšæããã®ã§ãç§ã¯ä»¥åã«çºèšããŸããã§ããã
é·ãé察å¿ããŠç³ãèš³ãããŸããã§ããããç§ã¯æã ãã®åé¡ãæ€èšããŠãããFlutterããŒã ããã®åçã«å€å°æžæã£ãŠããŸãã äž¡æ¹ã®æ¹æ³ã§ã¢ããªãè©ŠããŠã¿ãŠãéããèªåã§ç¢ºèªããã®ã«æéãããã£ãŠããªãããã§ãã
å ¬å¹³ãæãããã«ãããã¯ä¿¡ããããªãã»ã©é·ãã¹ã¬ããã§ããããã¬ãŒã ã¯ãŒã¯ã®åµèšè ã¯ãããã€ãã®è§£æ±ºçã§æ¯æ¥æ°åç©æ¥µçã«è²¢ç®ãããããã«é¢ãããã£ãŒãããã¯ãèŠæ±ãããããã«é¢äžããèŠæ±ãããŠãããã®ãç解ããããã«åãçµãã§ããŸããã ç§ã¯æ£çŽã«èšã£ãŠãã¡ã³ããã圹ç«ã€ãšããããæ確ãªäŸãèããã®ã«èŠåŽããŠããŸãã
ããããã®åé¡ã«ã€ããŠããå°ãå¿è匷ããªãã°ããã®ã§ããããã®ã¹ã¬ãããèªãã åŸã®ããã¯ã¯ã䜿ãæšãŠã®å¯¿åœãå·ã«çµã³ä»ããå¥ã®æ¹æ³ã§ãã以å€ã¯ããã以äžæ·±ãç解ããŠããŸããã ç§ã¯ãã®ã¢ãããŒããã¹ã¿ã€ã«çã«å¥œãŸãªãã®ã§ããã®äœçœ®ãããã©ãã€ã ã§ãŸã£ããæ°ããã¢ããªãæžãã®ã«æéããããã ãã§ããã¬ãŒã ã¯ãŒã¯ã«çµã¿èŸŒãŸããå¿ èŠãããçç±ãç解ã§ããã®ã§ããã°ãæ ¹æ¬çã«æ¬ é¥ããããšæããŸãïŒ ' -ãã®ã¹ã¬ããã§Reactãšã³ãžãã¢ãææããããã«ãFlutterã«ã¯å®éã«ã¯ãå§ãã§ããŸããããŸãããã®ã¹ã¬ããã§èª¬æãããŠããå©ç¹ã¯ãåé ç·ã®çš®é¡ã®ã³ã¹ããšæ¯èŒããŠå°ãããããå©ç¹ã確èªããã«ã¯ãŸã£ããæ°ããã³ãŒãããŒã¹ãå¿ èŠã§ãã
ç§ã¯æ£çŽã«èšã£ãŠãã¡ã³ããã圹ç«ã€ãšããããæ確ãªäŸãèããã®ã«èŠåŽããŠããŸãã
åæããŸããã ããã¯ãœã³ããã®è°è«ã«åå ããããã«æéãå²ããŠãããããšã«æè¬ããŸãã
ãã®ã¹ã¬ãããèªãã åŸãããã¯ãããæ·±ãç解ã§ããŸãã
å
¬å¹³ãæãããã«ããã®åé¡ã¯ããã¯ã«ã€ããŠå
·äœçã«è©±ãããšãæ確ã«é¿ããããšããŠããŸãã
ããã¯ã解決çã§ã¯ãªããåé¡ã説æããããšããããšã«é¢ãããã®ã§ã
ããªãã¯ããã倱æãããšæããŸããïŒ
ç§ã¯ããã§äž¡æ¹ïŒ @rrousselGitãš@HixieïŒãæããããšãã§ããFlutterãã¬ãŒã ã¯ãŒã¯ã®ïŒç§ã®ïŒäœ¿çšé¢/芳ç¹ããããã€ãã®ãã£ãŒãããã¯ãæ®ããããšæããŸããã
flutter_hooks
ã¢ãããŒãã¯ããã€ã©ãŒãã¬ãŒãã倧å¹
ã«åæžãïŒãã®ãããªç¶æ
æ§æãåå©çšã§ãããããããã«ç€ºãäŸããïŒããªãœãŒã¹ã®åæå/ç Žæ£ã«ã€ããŠç©æ¥µçã«èããå¿
èŠããªããããè€éãã軜æžãããŸãã äžè¬çã«èšãã°ãFlutterèªäœã®ãã³ã¢ãã«ïŒäž»èŠ³çã«ïŒããŸãé©åããŠããªããŠããéçºãããŒ/é床ãæ¹åããã³ãµããŒãããã®ã«é©ããŠããŸãã
ç§ãæžããã³ãŒãã®å°ãªããšã95ïŒ
ãè¶
ãããšãbuildã¡ãœããã¯å®£èšåã®ã¿ã«ãªããè¿ããããŠã£ãžã§ãããµãããªãŒã®å€éšã«ããŒã«ã«å€æ°ãåŒã³åºãã¯ãããŸããããã¹ãŠã®ããžãã¯éšåã¯ããªãœãŒã¹ãåæåãå²ãåœãŠãç Žæ£ããè¿œå ããããã®ç¶æ
é¢æ°ã®å
éšã«ãããŸãããªã¹ããŒïŒç§ã®å Žåã¯MobXã®åå¿ïŒãšãã®ãããªè«ççãªãã®ã ããã¯Flutterèªäœã®å€§éšåã®ã¢ãããŒãã§ããããããéåžžã«ãã€ãã£ããªæããããŸãã ããããããšã§ãéçºè
ã¯åžžã«æ瀺çã§ãããªããããŠããããšã«ã€ããŠãªãŒãã³ã«ãªãæ©äŒãåŸãããŸã-ãã®ãããªãŠã£ãžã§ãããåžžã«StatefulWidget
ã«å€æããinitState / disposeã§åæ§ã®ã³ãŒããæžãããšã匷å¶ããŸãããããã¯ãŸãåžžã«ã䜿çšãããŠãããŠã£ãžã§ããã§çŽæ¥å®è¡ããããšããŠããããšãæ£ç¢ºã«æžãçããããšã«ãªããŸãã å人çã«ã¯ã @ Hixieããã§ã«è¿°ã¹ãããã«ããã®çš®ã®å®åã³ãŒããæžãããšã¯ãŸã£ããæ°ã«ãªãããéçºè
ãšããŠã flutter_hooks
ãããªãã®ã«é Œãã®ã§ã¯ãªãããããæ£ããåŠçããæ¹æ³ã決å®ã§ããŸãã flutter_hooks
ã䜿çšãããšãããã¯ãšããŠèšè¿°ããŠåå©çšãã䟡å€ã®ããç¶æ
ã®çš®é¡ã«ã€ããŠèããå¿
èŠããããŸãããã¬ãŒããŒãç°ãªããšãããŸããŸãªã䜿ãæšãŠãããã¯ãçºçããããããã¯ããŸã£ãããªããªãå¯èœæ§ããããŸããæ§æãé »ç¹ã«åå©çšããããšã¯ãããŸããããããå€ãã®ã«ã¹ã¿ã æ§æãäœæããåŸåããããŸãã
誀解ããªãã§ãã ããããã®ãããªããã¯ã§ã®ã¢ãããŒãã¯éåžžã«çŽ æŽããã䟿å©ã«æããŸãããç§ã«ãšã£ãŠã¯ããããåŠçããæ¹æ³ã®ã³ã¢ã³ã³ã»ãããå€æŽããéåžžã«åºæ¬çãªã³ã³ã»ããã®ããã«æããŸãã éçºè ãããã€ãã£ãã«ããããè¡ãæ¹æ³ã«æºè¶³ããŠããªãå Žåã«ãã®çš®ã®ã¢ãããŒãã䜿çšããæ©äŒãéçºè ã«äžããããšã¯ãããã±ãŒãžèªäœãšããŠéåžžã«è¯ããšæããŸããããããFlutterãã¬ãŒã ã¯ãŒã¯èªäœã®äžéšã«ããããšã¯ãå°ãªããšãã¯ãªãŒã³ã§ããå¿ èŠããããŸã/çµ±äžãããçµæãFlutterã®å€§éšåãæžãçŽããŠãã®æŠå¿µãå©çšãããïŒå€ãã®äœæ¥ïŒãå°æ¥ã®/éžæããããã®ã«äœ¿çšããŸãïŒãã®ãããªæ··åã¢ãããŒãã§ã¯æ··ä¹±ããå¯èœæ§ããããŸãïŒã
ãããFlutterãã¬ãŒã ã¯ãŒã¯èªäœã«çµ±åããããµããŒããããŠãã/ç©æ¥µçã«äœ¿çšãããŠããå Žåãç§ã¯æããã«ããã«é£ã³ã€ããŸãã ç§ã¯çŸåšã®ã¢ãããŒããç解ããæ°ã«å ¥ã£ãŠãããããããã€ãã£ãã«å®è£ ããããã«å¿ èŠãªïŒå¯èœãªïŒã¢ã¯ã·ã§ã³ã確èªããŠããã®ã§ããããããå®è¡ãã¹ãã§ãªãçç±ãç解ããããã±ãŒãžãšããŠä¿æããããšãã§ããŸãã
ç§ãééã£ãŠããå Žåã¯èšæ£ããŠãã ããããã ãããã®ã¹ã¬ããã¯ãè€æ°ã®ãŠã£ãžã§ããã§ç¶æ ããžãã¯ãèªã¿ãããæ§æå¯èœãªæ¹æ³ã§åå©çšããåé¡ã«é¢ãããã®ã§ãã ç¹ã«ããã¯ããŸããã ãã®ã¹ã¬ããã¯ã解決çãã©ãããã¹ããã«ã€ããŠã®ãªãŒãã³ãªã¢ãããŒãã§åé¡ã«ã€ããŠè°è«ããããšããçç±ã§éããããšæããŸãã
ããã¯ã¯1ã€ã®è§£æ±ºçã§ããããèšåãããŠããŸããã @ rrousselGitã¯ããã§
ããã¯èšã£ãŠããçŸæç¹ã§ã¯ã¹ã¬ãããã©ãã«åãã£ãŠããã®ãããããŸããã
åé¡ã¯æ¬åœã«ååšãããšæããŸãã ãããšãç§ãã¡ã¯ããã«ã€ããŠè°è«ããŠããŸããïŒ
ä»æ¥ããã©ãã¿ãŒã®ã³ã¢ãæã€è€æ°ã®ãŠã£ãžã§ããã§ç¶æ
ããžãã¯ãæ§æå¯èœãªæ¹æ³ã§åå©çšããã®ãé£ããããšã«å
šå¡ãåæããŠããå Žåãã³ã¢ãœãªã¥ãŒã·ã§ã³ãšãªãå¯èœæ§ã®ãããœãªã¥ãŒã·ã§ã³ã¯ãããŸããïŒ ãã«ããŒã¯æ¬åœã«ïŒåŒçšããããã«ïŒ
ããªãèªã¿ã«ãã
ããããã£ãœãªã¥ãŒã·ã§ã³ã¯ããã»ã©ç°¡åã«åå©çšã§ããªãããã§ãããŸãã¯ã次ã®ç®çã§äœ¿çšããæ¹æ³ã«ã€ããŠã®åçããªãã£ããããééã£ãçµè«ãå°ãåºããŸããïŒïŒïŒã
å¥ã®ãŠã£ãžã§ããã®_ExampleStateå ã«çŸåšé 眮ãããŠããã³ãŒããåå©çšããã»ã«ã³ããªãŠã£ãžã§ãããäœæããŸããïŒ
ã²ãããå ããŠïŒãã®æ°ãããŠã£ãžã§ããã¯ããã®ç¶æ ã®å éšã§ãã®ãŠãŒã¶ãŒIDã管çããå¿ èŠããããŸã
@timsneathãææ¡ããããã«ã
çŸæç¹ã§ã¯ããã¶ã€ã³ããã¥ã¡ã³ããäœæãããšããã¢ã€ãã¢ã«ã¯ããªãæççã§ãã
ä»ã®ãšããã @ HixieãFlutterå
ã§ãã®åé¡ãçŽæ¥è§£æ±ºããããšã«å察ããŠããããšã¯æããã§ãã
ç§ã«ã¯ãåé¡ã®éèŠæ§ãšãã®åé¡ã解決ããäžã§ã®Googleã®åœ¹å²ã«ã€ããŠæèŠãåãããŠããããã«èŠããŸãã
åæ¹ãããã«åæããªãå Žåã解決çãäœã§ããããã®åé¡ã«åãçµãæ¹æ³ã«ã€ããŠçç£çãªè°è«ãè¡ãæ¹æ³ãããããŸããã
ãã®å·ã®ã¹ã¬ããã¯éåžžã«èå³æ·±ãèªã¿ç©ã§ãããæèŠäº€æãåžæ°çãªãã®ã§ããç¶ããŠããããšãå¬ããæããŸãã ããããç§ã¯çŸåšã®è¡ãè©°ãŸãã«å°ãé©ããŠããŸãã
ããã¯ã«é¢ããŠã¯ãFlutterã¯@rrousselGitã«ãã£ãŠæ瀺ãããç¹å®ã®ããã¯ãœãªã¥ãŒã·ã§ã³ãå¿ ãããå¿ èŠãšããªããã圌ã¯ããèšã£ãŠããªããšããã®ãç§ã®èŠè§£ã§ãã Flutterã«ã¯ãRemiãä»ã®æ¯æè ãèšåããŠãããã¹ãŠã®çç±ãããããã¯ãšåæ§ã®å©ç¹ãæäŸãããœãªã¥ãŒã·ã§ã³ãå¿ èŠã§ãã @ emanuel-lundmanã¯äžèšã®è°è«ãèŠçŽããŠãããç§ã¯åœŒã®èŠè§£ã«åæããŸãã
åãæ©èœãæäŸããä»ã®å®è¡å¯èœãªææ¡ããªããããã¯ãReactã§ååã«èšŒæãããå®çžŸãæã£ãŠãããšããäºå®ãšãFlutterã®ããŒã¹ãšãªãå¯èœæ§ã®ããæ¢åã®ãœãªã¥ãŒã·ã§ã³ãããããšãèãããšããããªããšã¯æããŸãããããããã®ã¯æªãéžæã§ãã Flutter SDKïŒãŸãã¯ãã以äžïŒã«ãå«ãŸããŠããããªããã£ããšããŠã®ããã¯ã®æŠå¿µããFlutterããäœãã奪ãããšã¯ãªããšæããŸãã ç§ã®æèŠã§ã¯ãããã¯ãããè±ãã«ããFlutterã§ä¿å®å¯èœã§æ¥œããã¢ããªãéçºããããšãããã«ç°¡åã«ããã ãã§ãã
ããã¯ã¯ãã®æ©æµã享åããã人ã®ããã®ããã±ãŒãžãšããŠå©çšå¯èœã§ãããšããè°è«ã¯æå¹ãªãã€ã³ãã§ãããããã¯ã®ãããªããªããã£ãã«ã¯æé©ã§ã¯ãªããšæããŠããŸãã ãããçç±ã§ãã
å éšã§åå©çšå¯èœãªããã±ãŒãžãäœæããå Žåã§ããDart + Flutter SDKã«ã®ã¿äŸåãããšããæå³ã§ãããã±ãŒãžããçŽç²ãã«ããå¿ èŠããããã©ããããŸãã¯ä»ã®ããã±ãŒãžãèš±å¯ãããã©ããã«ã€ããŠè°è«ããããšããããããŸãããã®ã ãããã€ããŒã§ãããçŽç²ãªãããã±ãŒãžãæ±ããŠããŸãããå€ãã®å Žåãããé«ãã¬ãã«ã®ããã±ãŒãžãæ±ããŠããŸãã ã¢ããªã®å Žåãã©ã®ããã±ãŒãžãåé¡ãªãããã©ã®ããã±ãŒãžãåé¡ãªãããšããåãè°è«ãåžžã«ãããŸãã ãããã€ããŒã¯ç·è²ã§ãããããã¯ã®ãããªãã®ã¯ãŸã ããã±ãŒãžãšããŠçå笊ã§ãã
ãœãªã¥ãŒã·ã§ã³ã®ãããªããã¯ãSDKã®äžéšã§ããå ŽåããããæäŸããæ©èœã䜿çšããããšã¯æãããªéžæã§ãã ããã¯ã䜿çšããŠãããã±ãŒãžãšããŠãã§ã«èš±å¯ãããã®ã§ããããããFlutterã³ãŒãã¹ã¿ã€ã«ãäœæããããã䜿çšããŠããªãFlutteréçºè ã«ã¯ãªãã¿ã®ãªãæŠå¿µãå°å ¥ããããšãæžå¿µããŠããŸãã SDKã§ãµããŒããããŠããªãç¶æ ã§ãã®ãã¹ããã©ããšãéè·¯ã®åå²ç¹ã®ããã«æããŸãã å°èŠæš¡ãªå人ãããžã§ã¯ãã®å Žåãããã¯ã䜿çšããã®ã¯ç°¡åãªéžæã§ãã Riverpodãšäžç·ã«è©Šãããšããå§ãããŸãã
ïŒç§ãã¡ã®ããã±ãŒãžã®ä¿å®æ§ã¯ãéå»ã«ããã±ãŒãžã«ãã£ãŠçŒãä»ããããããä»ã®ããã±ãŒãžãããŒãžã£ãŒã«äŸåãããããããšããæ¥ãŠãããšæããŸãããããããäžæã§ã¯ãããŸãããïŒ
ãããŸã§ã«å®èšŒãããå¯äžã®è§£æ±ºçã§ãã£ãŠããããã¯ãçŸåšã®åé¡ã解決ããå¯äžã®æ¹æ³ã§ãããšèšã£ãŠããããã§ã¯ãããŸããã ãœãªã¥ãŒã·ã§ã³ã«ã³ãããããåã«ãããäžè¬çãªã¬ãã«ã§ãªãã·ã§ã³ã調æ»ããããšã¯ã確ãã«èå³æ·±ããæå¹ãªã¢ãããŒãã§ããå¯èœæ§ããããŸãã ãã®ããã«ã¯ãFlutter SDKã_çŸåšãç°¡åã«åå©çšå¯èœãªç¶æ ããžãã¯ã«é¢ããŠæ¬ é¥ããã_ãšããèªèãå¿ èŠã§ããããã¯ã詳现ãªèª¬æã«ãããããããçŸåšã¯ããã§ã¯ãªãããã§ãã
ç§ã«ãšã£ãŠãããã¯ãã³ã¢ãã¬ãŒã ã¯ãŒã¯ã«å ¥ããã ãã§ã¯ãªãäž»ãªçç±ã¯2ã€ãããŸãã 1ã€ç®ã¯ãAPIã«å±éºãªãã©ãããå«ãŸããŠããããšã§ãã äž»ã«ãã©ããããããééã£ãé åºã§ããã¯ãåŒã³åºãããšã«ãªã£ãå Žåãç©äºã¯å£ããŸãã ããã¯ç§ã«ã¯èŽåœçãªåé¡ã®ããã«æããŸãã ç§ã¯ãèŠåŸãšããã¥ã¡ã³ãã«åŸãããšã§ãããåé¿ã§ããããšãç解ããŠããŸãããç§èŠã§ã¯ããã®ã³ãŒãåå©çšã®åé¡ã«å¯Ÿããåªãã解決çã«ã¯ãã®æ¬ é¥ã¯ãããŸããã
2ã€ç®ã¯ããã®åé¡ã解決ããããã«ããã¯ïŒãŸãã¯å¥ã®ã©ã€ãã©ãªïŒã䜿çšã§ããªãçç±ã¯å®éã«ã¯ãªãã¯ãã§ãã ããŠã人ã ãè°è«ããããã«ãããã¯ã䜿çšãããšãç¹ã«ããã¯æ©èœããŸãããããã¯ãæžãããšã¯ãç¡é¢ä¿ã®ã©ã€ãã©ãªãããã¯ããµããŒãããããšã人ã ãæãã»ã©è² æ ã倧ããããã§ãã ããããç§ã¯ãã®åé¡ã®è¯ã解決çã¯ãããå¿ èŠãšããªãã ãããšæããŸãã åªãããœãªã¥ãŒã·ã§ã³ã¯ã¹ã¿ã³ãã¢ãã³ã§ãããä»ã®ãã¹ãŠã®ã©ã€ãã©ãªãããã«ã€ããŠç¥ãå¿ èŠã¯ãããŸããã
æè¿ãRestorablePropertiesããã¬ãŒã ã¯ãŒã¯ã«è¿œå ããŸããã ããããããã§äœããã®åœ¢ã§æŽ»çšã§ãããã©ããã確èªããã®ã¯èå³æ·±ãã§ããã...
ã¢ãã©ã€ã¶ãŒãŸãã¯ãªã³ã¿ãŒã解決ããå¿ èŠãããé ããåé¡ãããAPIã«ã€ããŠ@Hixieã«åæããŸãã ç§ãã¡ã¯ãåå ããã人ãšåãããã«ãåå©çšå¯èœãªã©ã€ããµã€ã¯ã«ç®¡çã®åé¡ã«ã€ããŠãããããèšèšããã¥ã¡ã³ãã®ææ¡ãéããŠããŸãã¯ãã®ä»ã®æ¹æ³ã§ãããŸããŸãªè§£æ±ºçãæ€èšããå¿ èŠããããšæããŸãã çæ³çã«ã¯ãFlutteråºæã§ãããFlutter APIã掻çšããªãããããã¯APIãè¡ãåé¡ã解決ããŸãã VueããŒãžã§ã³ã¯ãããã¯ã®åŒã³åºãé åºã«äŸåããªããããåè¿°ããããã«ãæåããå§ããã®ã«é©ããã¢ãã«ã ãšæããŸãã ä»ã«ç§ãšäžç·ã«èª¿æ»ããããšã«èå³ããã人ã¯ããŸããïŒ
@Hixieã§ããããŠã£ãžã§ããéã§æ§æå¯èœãªæ¹æ³ã§ç¶æ ããžãã¯ãåå©çšããè¯ãæ¹æ³ããªããšããåé¡ã«åæããŸããïŒ ã ãããã©ããããããResuablePropertiesã掻çšããããšãèãå§ããã®ã§ããïŒ
ç§ã«ãšã£ãŠãããã¯ãã³ã¢ãã¬ãŒã ã¯ãŒã¯ã«å ¥ããã ãã§ã¯ãªãäž»ãªçç±ã¯2ã€ãããŸãã 1ã€ç®ã¯ãAPIã«å±éºãªãã©ãããå«ãŸããŠããããšã§ãã äž»ã«ãã©ããããããééã£ãé åºã§ããã¯ãåŒã³åºãããšã«ãªã£ãå Žåãç©äºã¯å£ããŸãã ããã¯ç§ã«ã¯èŽåœçãªåé¡ã®ããã«æããŸãã ç§ã¯ãèŠåŸãšããã¥ã¡ã³ãã«åŸãããšã§ãããåé¿ã§ããããšãç解ããŠããŸãããç§èŠã§ã¯ããã®ã³ãŒãåå©çšã®åé¡ã«å¯Ÿããåªãã解決çã«ã¯ãã®æ¬ é¥ã¯ãããŸããã
ããã¯ã䜿ã£ãããããã¯ã䜿ã£ãŠããä»ã®äººãšäžç·ã«åãããããããšãããããã¯ç§èŠã§ã¯ããã»ã©å€§ããªåé¡ã§ã¯ãããŸããã ãããŠã圌ããããŒãã«ã«ãããããã¹ãŠã®å€§ããªå©çïŒéçºé床ãåå©çšæ§ãæ§æå¯èœæ§ãããã³èªã¿ãããã³ãŒãã®å€§ããªå©çïŒãšã¯ãŸã£ããæ¯èŒãããŸããã
ããã¯ã¯ãã¯ã©ã¹ãåãªãé¢æ°ã§ã¯ãªãã¯ã©ã¹ã§ããããã«ããã¯ã§ãããæ¡ä»¶ä»ãã§äœ¿çšããããšã¯ã§ããŸããã ããªãã¯ãããéãåŠã³ãŸãã ãŸããç·šéè
ã¯ãã®åé¡ã«ã€ããŠãæ¯æŽã§ããŸãã
2ã€ç®ã¯ããã®åé¡ã解決ããããã«ããã¯ïŒãŸãã¯å¥ã®ã©ã€ãã©ãªïŒã䜿çšã§ããªãçç±ã¯å®éã«ã¯ãªãã¯ãã§ãã ããŠã人ã ãè°è«ããããã«ãããã¯ã䜿çšãããšãç¹ã«ããã¯æ©èœããŸãããããã¯ãæžãããšã¯ãç¡é¢ä¿ã®ã©ã€ãã©ãªãããã¯ããµããŒãããããšã人ã ãæãã»ã©è² æ ã倧ããããã§ãã ããããç§ã¯ãã®åé¡ã®è¯ã解決çã¯ãããå¿ èŠãšããªãã ãããšæããŸãã åªãããœãªã¥ãŒã·ã§ã³ã¯ã¹ã¿ã³ãã¢ãã³ã§ãããä»ã®ãã¹ãŠã®ã©ã€ãã©ãªãããã«ã€ããŠç¥ãå¿ èŠã¯ãããŸããã
ããã¯ãæžãã®ã¯é¢åã§ã¯ãããŸããã
çŸåšå©çšå¯èœãªãœãªã¥ãŒã·ã§ã³ããããŸã ç°¡åã§ãïŒãã®ãã¬ãŒãºãããäžåºŠäœ¿çšããðïŒã
å€åç§ã¯ããªããæžããŠãããã®ã誀解ããŠããŸãã ããããç§ã¯èª°ããããèšã£ããšã¯æããªãã®ã§ããïŒ
ç§ã¯ãããã¯ãœãªã¥ãŒã·ã§ã³ãããŒãã«ã«ãããããã¹ãŠã®å©ç¹ã人ã
ãæ¬åœã«æè¬ããã©ãã§ãããã䜿çšã§ããããšãæãã§ããããã«ãããèªã¿ãŸããã ãã¹ãŠã®ã¡ãªããã享åããã ããã¯ã¯åå©çšå¯èœã§ããããããµãŒãããŒãã£ã®éçºè
ããå
šå¡ãç¬èªã®ã©ãããŒãäœæããªããŠããèªä¿¡ãæã£ãŠç¬èªã®ããã¯ãã³ãŒãã£ã³ã°ããŠåºè·ã§ããã°çŽ æŽããããšæããŸãã ç¶æ
ããžãã¯ã®åå©çšæ§ã®ã¡ãªããã享åããŸãã
@rrousselGitãš@gaearonã¯ãã§ã«åå§çãªããšã説æããŠãããšæããŸãã ã ããç§ã¯ããã«ã¯å
¥ããŸããã
ãã¶ãããã®ã¹ã¬ããã§äººã
ãæžãããã®ã®è¯ãèŠçŽã§ããããšãããããªãã®ã§ãç§ã¯ãã®å£°æãåãåããªãã§ãããã ããããªããã
åé²ããæ¹æ³ãããããšãé¡ã£ãŠããŸãã ããããå°ãªããšããããåé¡ã§ããããšã«åæããããã¯ãããŒãã«ã«ãããªãããã«èŠããã®ã§ãããè¯ã代æ¿ãœãªã¥ãŒã·ã§ã³ãèãåºãæãæ¥ããšæããŸãã
ãŸãã¯ããã©ãã¿ãŒã³ã¢ã®åé¡ã®ä¿®æ£ãã¹ãããããããšã決å®ããŸãã
誰ãåé²ãããã決ããã®ã§ããïŒ
次ã®ã¹ãããã¯äœã§ããïŒ
ããã¯ç§ã«ã¯èŽåœçãªåé¡ã®ããã«æããŸãã ç§ã¯ãèŠåŸãšããã¥ã¡ã³ãã«åŸãããšã§ãããåé¿ã§ããããšãç解ããŠããŸãããç§èŠã§ã¯ããã®ã³ãŒãåå©çšã®åé¡ã«å¯Ÿããåªãã解決çã«ã¯ãã®æ¬ é¥ã¯ãããŸããã
Reactã§ã¯ãããããªã³ã¿ãŒïŒéçåæïŒã§è§£æ±ºããŸãã ç§ãã¡ã®çµéšã§ã¯ããã®æ¬ é¥ã¯å€§èŠæš¡ãªã³ãŒãããŒã¹ã§ãéèŠã§ã¯ãããŸããã§ããã æ¬ é¥ãšèŠãªãããå¯èœæ§ã®ããåé¡ã¯ä»ã«ããããŸãããæ°žç¶çãªåŒã³åºãé åºãžã®äŸåã¯äººã ãçŽæçã«åé¡ã«ãªããšèãããã®ã§ãããå®éã«ã¯ãã©ã³ã¹ãããªãç°ãªãããšãææããããšæããŸãã
ç§ããã®ã³ã¡ã³ããæžããŠããæ¬åœã®çç±ã¯ãFlutterãã³ã³ãã€ã«ãããèšèªã䜿çšããŠããããã§ãã ããªã³ãã£ã³ã°ãã¯ãªãã·ã§ã³ã§ã¯ãããŸããã ãããã£ãŠããã¹ãèšèªãšUIãã¬ãŒã ã¯ãŒã¯ã®éã«æŽåæ§ãããå Žåããæ¡ä»¶ä»ããåé¡ãéçã«çºçããªãããã«åŒ·å¶ããããšã¯ééããªãå¯èœã§ãã ãã ããããã¯ãUIãã¬ãŒã ã¯ãŒã¯ãèšèªã®å€æŽãåæ©ä»ããããšãã§ããå Žåã«ã®ã¿æ©èœããŸãïŒäŸïŒCompose + KotlinïŒã
@Hixieã§ããããŠã£ãžã§ããéã§æ§æå¯èœãªæ¹æ³ã§ç¶æ ããžãã¯ãåå©çšããè¯ãæ¹æ³ããªããšããåé¡ã«åæããŸããïŒ ã ãããã©ããããããResuablePropertiesã掻çšããããšãèãå§ããã®ã§ããïŒ
ããã¯ç¢ºãã«äººã ãè²ãŠãŠãããã®ã§ãã ããã¯ç§ãå èã®çµéšãæã£ãŠãããã®ã§ã¯ãããŸããã Flutterã䜿ã£ãŠèªåã®ã¢ããªãæžããšãã«åé¡ã ãšæãããã®ã§ã¯ãããŸããã ããããããã¯äžéšã®äººã ã«ãšã£ãŠãããæ¬åœã®åé¡ã§ã¯ãªããšããæå³ã§ã¯ãããŸããã
ããã¯ã¯åå©çšå¯èœã§ããããããµãŒãããŒãã£ã®éçºè ããå šå¡ãç¬èªã®ã©ãããŒãäœæããªããŠããèªä¿¡ãæã£ãŠç¬èªã®ããã¯ãã³ãŒãã£ã³ã°ããŠåºè·ã§ããã°çŽ æŽããããšæããŸãã
ç§ã®ãã€ã³ãã¯ãããã§ã®åªãããœãªã¥ãŒã·ã§ã³ã§ã¯ãã©ãããŒãäœæããå¿ èŠããªããšããããšã§ãã
次ã®ã¹ãããã¯äœã§ããïŒ
次ã®ã¹ãããã¯ãããããããŸããäŸïŒ
ãã®å·ã®ã¹ã¬ããã¯éåžžã«èå³æ·±ãèªã¿ç©ã§ãããæèŠäº€æãåžæ°çãªãã®ã§ããç¶ããŠããããšãå¬ããæããŸãã
ãã®æãç§ã¯éåžæ°ã®ç³žãã©ã®ããã«èŠããããèŠãããããŸããã ãã®ã¹ã¬ããã«ã¯å ±æãã»ãšãã©ãªãã®ã§ãå芳è ããèªãã ããã©ããŒãããããã®ã¯å°é£ã§ãã
ç§ã®ãã€ã³ãã¯ãããã§ã®åªãããœãªã¥ãŒã·ã§ã³ã§ã¯ãã©ãããŒãäœæããå¿ èŠããªããšããããšã§ãã
ãã ããã©ãããŒãäœæããå¿ èŠã¯ãããŸããã ããããæ £ã芪ããã ç¬èªã®ã³ãŒãã§ãã¡ãªãããšåå©çšæ§ã享åãããå ŽåããããŸãã 確ãã«ãã©ã€ãã©ãªããã®ãŸãŸäœ¿çšããããšã¯ã§ããŸãã ããã¯ã©ããã³ã°ãæžãå ŽåïŒå¯èœã§ããã°ïŒãããã¯ããããè² æ ã ãšæã£ãŠããããã§ã¯ãªããä»ã®æ¹æ³ãããåªããŠãããšããããšã§ãã
ããã¯å®éã«ã¯æ£åœãªçç±ã§ããããã®ã¹ã¬ããã®åé¡ã®è§£æ±ºçãã³ã¢ã§åªããŠããçç±ãè¿°ã¹ãããŠããŸãã ã³ã¢å ã®åå©çšå¯èœãªæ§æå¯èœãªç¶æ ããžãã¯ãœãªã¥ãŒã·ã§ã³ã¯ãäŸåé¢ä¿ãè¿œå ããã«ãã¹ãŠã®ããã±ãŒãžã§å®å šã«åºè·ã§ãããããã©ãããŒãäœæããå¿ èŠããªãããšãæå³ããŸãã
ã³ã¢å ã®åå©çšå¯èœãªæ§æå¯èœãªç¶æ ããžãã¯ãœãªã¥ãŒã·ã§ã³ã¯ãäŸåé¢ä¿ãè¿œå ããã«ãã¹ãŠã®ããã±ãŒãžã§å®å šã«åºè·ã§ãããããã©ãããŒãäœæããå¿ èŠããªãããšãæå³ããŸãã
ç§ãèšãããã®ã¯ãIMHOã®åªãããœãªã¥ãŒã·ã§ã³ã§ã¯ããã®ããžãã¯ãäœæããããã«_誰ã_ãå¿ èŠãšããªããšããããšã§ãã åå©çšããåé·ãªããžãã¯ã¯ãããŸããã ããšãã°ãåã®ãfetchUserãã®äŸãèŠããšããfetchUserãé¢æ°ãåŒã³åºãããã«ããã¯ãŸãã¯ããã«çžåœãããã®ãäœæããå¿ èŠã¯ãªãããfetchUserãé¢æ°ãçŽæ¥åŒã³åºãã ãã§ãã åæ§ã«ããfetchUserãã¯ããã¯ïŒãŸãã¯ç§ãã¡ã䜿çšãããã®ïŒã«ã€ããŠäœãç¥ãå¿ èŠã¯ãªããããã¯ïŒãŸãã¯ç§ãã¡ã䜿çšãããã®ïŒã¯ãfetchUserãã«ã€ããŠäœãç¥ãå¿ èŠã¯ãããŸããã ããã¯ã®å Žåã®ããã«ãæžãããžãã¯ãç°¡åã«ä¿ã¡ãªãããã¹ãŠã
çŸåšã®å¶éã¯ãããã¯ãèšèªå¶éã«å ããŠãããã§ãããšããäºå®ã«ãã£ãŠåŒãèµ·ããããŠããŸãã
äžéšã®èšèªã§ã¯ãããã¯ã¯æ¬¡ã®ãããªèšèªæ§é ã§ãã
state count = 0;
return RaisedButton(
onPressed: () => count++,
child: Text('clicked $count times'),
)
ããã¯ãéåæ/ syncé¢æ°ã®å€åœ¢ã§ãããåŒã³åºãå šäœã§ããã€ãã®ç¶æ ãä¿æã§ããŸãã
èšèªã®äžéšãšããŠãåå€æ°ãã¿ã€ãã§ã¯ãªãè¡çªå·ã§åºå¥ã§ãããããç¡æ¡ä»¶ã§äœ¿çšããå¿ èŠããªããªããŸããã
ããã¯ã®å¶éã¯--track-widget-creationã®å¶éã«äŒŒãŠããããšãä»ãå ããŠãããŸãã
ãã®ãã©ã°ã¯ããŠã£ãžã§ããã®constã³ã³ã¹ãã©ã¯ã¿ãŒã®æ£èŠåã解é€ããŸãã ãããããŠã£ãžã§ããã¯å®£èšåã§ãããããããã¯åé¡ã§ã¯ãããŸããã
ãã®æå³ã§ãããã¯ã¯åãã§ãã å¶éã¯å®£èšçã«æäœããããããå®éã«ã¯éèŠã§ã¯ãããŸããã
ä»ã®ããã¯ãèªãŸãªããšã1ã€ã®éåžžã«å
·äœçãªããã¯ãååŸããããšã¯ã§ããŸããã
ãã¶ããfetchuserã®äŸã¯çæ³çãªäŸã§ã¯ãããŸããã
ãã ããuseStreamãuseAnimstionããŸãã¯useStreamCintrollerã䜿çšãããšããŠã£ãžã§ããããªãŒãããã¯ãªãŒã³ã«ãªããç Žæ£ãå¿ããããdudChangeDependencuesãåŠçãããããã®ãé²ãããšãã§ããŸãã
ãããã£ãŠãçŸåšã®æ¹æ³ã«ã¯ãå·»ã蟌ãŸããå¯èœæ§ã®ãããã©ããããããŸãããããã£ãŠãåŒã³åºãã·ãŒã±ã³ã¹ã®æœåšçãªåé¡ã¯ããããã»ã©å€§ããªåé¡ã§ã¯ãªããšæããŸãã
èªåã§ããã¯ãæžãå§ãããã©ããã¯ããããŸãããããã¬ãŒã ã¯ãŒã¯å
ã§äœ¿çšã§ããããã«ãé »ç¹ã«å¿
èŠãšãªãã³ã¬ã¯ã·ã§ã³ãçšæããŠãããšäŸ¿å©ã§ãã
ããã¯ãããã«å¯ŸåŠããããã®ä»£æ¿æ¹æ³ã«ãããŸããã
@Hixie ãããªãã説æããããšããŠããããšãç解ã§ããªããŠæ¬åœã«ç³ãèš³ãããŸãããç§ã¯ããã§å€é ãã ãšéé£ããŸãããããããããã¯ç§ã ãã§ãð³..ããããããªãã説æããè¯ã解決çã§ã¯ãå·ã®äŸ¡å€ã¯ã©ãã«ãããŸããïŒåé¡ã®è§£æ±ºçãç°¡åã«æ§æå¯èœã§ãŠã£ãžã§ããéã§å ±æã§ããããã«ã©ãã/ã«ãã»ã«åããç¶æ ã®ããžãã¹ããžãã¯ãšã©ã€ãã¿ã€ã ã€ãã³ãããžãã¯ãååšããŸããïŒ è¯ã解決çãäœãããã®ãããããŠãããçæ³çã«ã©ã®ããã«æ©èœããã®ãã«ã€ããŠå°ã詳ãã説æããŠããã ããŸããïŒ
ãã®è°è«ã®ç€Œåæ£ããã«ã€ããŠã®èšåãããã®ãèŠãŠãããã§å°ãä»å ¥ããã ãã§ãã ç§ã¯å人çã«ãããã®èª°ããéåžæ°çã§ãããšã¯æããŠããŸããã
ãšã¯ãããããã¯ããããé¢ã§äººã ãæ·±ãé¢å¿ãæã£ãŠãããããã¯ã§ããããšã¯æ³šç®ã«å€ãããšæããŸãã
package:provider
課é¡è¿œè·¡ã·ã¹ãã ã§ã®ç¶æ
管çã«é¢ããåå¿è
ã®è³ªåã«äœå¹ŽãåçããŠããŸããã ç§ã¯ãããã®æ¶é²ããŒã¹ã®åŸè
ã ãããã©ããŒããŠãããã¬ãã®å€åããšå¿èãå°éããŠããã ãã§ãããã®è°è«ã®ãã¹ãŠã®åœäºè ãã圌ããäœãããŠããã®ãã«ã€ããŠè°è«ããæ£åœãªçç±ãããããšã¯æããã§ãã ã¡ãã»ãŒãžãäŒããã®ã«æéããããããšãç解ã§ããŸãã
ã§ãããããããä»ã®åœ¢ã§è°è«ãç¶ããããã°å¹žãã§ãã æ£åŒãªããã¥ã¡ã³ãã®ããã«ããªãããã®åœ¢ã§ãµããŒãã§ããå Žåã¯ããç¥ãããã ããã
äžæ¹ãããã§ã®è°è«ãæã«è² ããªããªã£ãŠãããšäººã ãèããå Žåã¯ãäžæåæ¢ããŠãããè¯ãã³ãã¥ãã±ãŒã·ã§ã³æ¹æ³ããããã©ããã確èªããŸãããã
ïŒãããšã¯å¥ã«ããã®ãã£ã¹ã«ãã·ã§ã³ã«åå ããŠããã@gaearonã«äžèšãé¡ãããŸãããã®ç¹ã§ã®Reactã®çµéšã¯éåžžã«è²Žéã§ããïŒ
@ emanuel-lundman
ããããããªãã説æããåªãããœãªã¥ãŒã·ã§ã³ã§ã¯ãåé¡ã®ãœãªã¥ãŒã·ã§ã³ãç°¡åã«æ§æå¯èœã§ãŠã£ãžã§ããéã§å ±æã§ããããã«ã©ãã/ã«ãã»ã«åããç¶æ å€ãç¶æ ããžãã¹ããžãã¯ãããã³ã©ã€ãã¿ã€ã ã€ãã³ãããžãã¯ã¯ã©ãã«ãããŸããïŒ è¯ã解決çãäœãããã®ãããããŠãããçæ³çã«ã©ã®ããã«æ©èœããã®ãã«ã€ããŠå°ã詳ãã説æããŠããã ããŸããïŒ
æ®å¿µãªãããããããªãã®ã§è©³ãã説æã§ããŸããã :-)
@escamoteur
ãã¶ããfetchuserã®äŸã¯çæ³çãªäŸã§ã¯ãããŸããã
ãã ããuseStreamãuseAnimstionããŸãã¯useStreamCintrollerã䜿çšãããšããŠã£ãžã§ããããªãŒãããã¯ãªãŒã³ã«ãªããç Žæ£ãå¿ããããdudChangeDependencuesãåŠçãããããã®ãé²ãããšãã§ããŸãã
ãã®åé¡ã®é£ããã®1ã€ã¯ãåé¡ãèšè¿°ãããŠããããŽãŒã«ãã¹ãã®ç§»åãã§ããããã®åŸãåé¡ãåæããããšãåé¡ã¯å®éã®åé¡ã§ã¯ãªããšããŠåŽäžãããæ°ããåé¡ãèšè¿°ãããŸãã æ¬åœã«åœ¹ç«ã€ãããããªãã®ã¯ãããã€ãã®æšæºçãªäŸãèãåºãããšã§ããããšãã°ãåé¡ã®å®éã®äŸãå«ããã¢Flutterã¢ããªã±ãŒã·ã§ã³ã¯ã説æã®ããã«é床ã«åçŽåãããŠããŸããã 次ã«ãããã¯ããã®ä»ã®ææ¡ã䜿çšããŠãããåå®è£ ããå ·äœçã«çžäºã«è©äŸ¡ããããšãã§ããŸãã ïŒåé¡ãäœã§ããããæ£ç¢ºã«ç解ããŠããªãå Žåãé€ããŠãç§ã¯èªåã§ãããè¡ããŸãããããã£ãŠãããã¯ãæ¯æãã誰ãããããè¡ãã®ãããããæåã§ããïŒ
æ¬åœã«åœ¹ç«ã€ãããããªãã®ã¯ãããã€ãã®æšæºçãªäŸãèãåºãããšã§ããããšãã°ãåé¡ã®å®éã®äŸãå«ããã¢Flutterã¢ããªã±ãŒã·ã§ã³ã§ããã説æã®ããã«é床ã«åçŽåãããŠããªããã®ã§ãã
ç§ãããã§æããäŸã«ã€ããŠã©ãæããŸããïŒ https://github.com/flutter/flutter/issues/51752#issuecomment -669626522
ããã¯å®éã®ã³ãŒãã¹ããããã§ãã
ããã¯çŽ æŽãããã¹ã¿ãŒãã«ãªããšæããŸãã ããã¯ã䜿çšããªãããŒãžã§ã³ãšäœ¿çšããããŒãžã§ã³ã§ãã¹ã¿ã³ãã¢ãã³ã¢ããªãšããŠå®è¡ã§ããç¶æ ã«ããããšã¯ã§ããŸããïŒ
ç³ãèš³ãããŸããããç§ã¯ã¢ããªã§ã¯ãªããã³ãŒãã¹ãããããæå³ããŠããŸããã
ããã¢ãã©ãã¿ãŒã¢ããªã±ãŒã·ã§ã³ãã®ã¢ã€ãã¢ã®åé¡ã®1ã€ã¯ããã®ã¹ã¬ããã§äœæãããäŸãéåžžã«çŸå®çã§ãããšããããšã ãšæããŸãã
ãããã¯åçŽåãããããŠããŸããã
ãããŠã³ã¹ãã€ãã³ããã³ãã©ãŒããµãã¹ã¯ãªãã·ã§ã³ãæé»çãªå¯äœçšãªã©ã®ãã€ã¯ãç¶æ
ãå æ°å解ããå Žåã®ããã¯ã®äž»ãªäœ¿çšäŸâããããçµã¿åãããŠããæçšãªããžãã¯ãå®çŸããŸãã
https://marvel.riverpod.dev/#/ãªã©ã®Riverpodã«é¢ããããã€ãã®äŸããããŸããããã§ããœãŒã¹ã³ãŒãã¯æ¬¡ã®ãšããã§ããhttps ïŒ
ããããããã¯ãããŸã§ã«èšåããããã®ãšããã»ã©å€ãããªãã§ãããã
@Hixie
ãªããããåé¡ãªã®ãç解ããã®ã«æ¬åœã«èŠåŽããŠããŸãã Flutterã¢ããªã±ãŒã·ã§ã³ãããããæžããã®ã§ãããããã»ã©åé¡ã«ã¯ãªããªãããã§ãã ææªã®å Žåã§ããããããã£ã宣èšããåæåããç Žæ£ãããããã°ããŒã¿ã«å ±åããã®ã¯4è¡ã§ãïŒéåžžãåæåããã®ãšåãè¡ã§å®£èšã§ãããããéåžžã¯å°ãªããªããŸããã¢ããªã¯äžè¬çã«ãããã°ããããã£ã«ç¶æ ãè¿œå ããããšãå¿é ããå¿ èŠã¯ãããŸããããããã®ãªããžã§ã¯ãã®å€ãã«ã¯ãç Žæ£ããå¿ èŠã®ããç¶æ ããããŸããïŒã
ç§ã¯åãè¹ã«ä¹ã£ãŠããŸãã
確ãã«ãããã§èª¬æãããŠããåé¡ãããããããŸããã åå©çšå¯èœã§ããå¿
èŠãããã人ã
ãåç
§ãããç¶æ
ããžãã¯ããäœã§ãããããç解ããŠããŸããã
ã¹ããŒããã«ãã©ãŒã ãŠã£ãžã§ãããããããããããã®äžã«ã¯æ°åã®ãã©ãŒã ãã£ãŒã«ãããããã®ããããããã¹ãã³ã³ãããŒã©ãŒãšãã©ãŒã«ã¹ããŒããèªåã§ç®¡çããå¿
èŠããããŸãã ã¹ããŒãã¬ã¹ãŠã£ãžã§ããã®ã©ã€ããµã€ã¯ã«ã¡ãœããã§ããããäœæããŠç Žæ£ããŸãã éåžžã«é¢åã§ãããåãéã®ã³ã³ãããŒã©ãŒ/ focusNodeã䜿çšãããŠã£ãžã§ãããåããŠãŒã¹ã±ãŒã¹ã䜿çšãããŠã£ãžã§ããã¯ãããŸããã ãããã®éã®å¯äžã®å
±éç¹ã¯ãã¹ããŒããã«ã§ããããã©ãŒã ã§ãããšããäžè¬çãªæŠå¿µã§ãã ãã¿ãŒã³ã ãããšãã£ãŠãã³ãŒããç¹°ãè¿ãããããã§ã¯ãããŸããã
ã€ãŸããã³ãŒãã®å€ãã®éšåã§é
åãã«ãŒãããå¿
èŠããããã¢ããªã®ç¹°ãè¿ãã³ãŒãå
šäœã§ãforïŒvarthing inthingsïŒããå®è¡ããããšã¯ãããŸããã
ã©ã€ããµã€ã¯ã«APIã®ã·ã³ãã«ãããçãŸããStatefulWidgetã®ãã¯ãŒã倧奜ãã§ãã ããã«ããã1ã€ã®ããšãå®è¡ããã¢ããªã®ä»ã®éšåããåé¢ããŠå®è¡ããStatefulWidgetsãäœæã§ããŸãã ãŠã£ãžã§ããã®ãç¶æ ãã¯åžžã«ãã©ã€ããŒãã§ããããããŠã£ãžã§ããã®åå©çšã¯åé¡ã§ã¯ãªããã³ãŒãã®åå©çšãåé¡ã§ã¯ãããŸããã
ããã§åãäžããäŸã«ã¯ããã€ãåé¡ããããŸãããããã¯ããªãã®äž»åŒµãšããçšåºŠäžèŽããŠããŸãã
ããã¯ããªãèªã¿ã«ãããªããŸãã
- 10ã¬ãã«ã®ã€ã³ãã³ãããããŸãâãã£ã«ã¿ãŒããžãã¯ãåå©çšããããã«
FilterBuilder
ãäœæãããš12ã¬ãã«ã«ãªããŸããã£ã«ã¿ããžãã¯ã¯ãçŸç¶ã§ã¯åå©çšã§ããŸããã
- 誀ã£ãŠ
timer
ããã£ã³ã»ã«ããã®ãå¿ããå¯èœæ§ããããŸãbuild
ã¡ãœããã®ååã¯èªè ã«ã¯åœ¹ã«ç«ã¡ãŸããã ãã«ããŒã¯éèŠãªããšããç§ãã¡ã®æ°ãããããŸã- æ¬åŒ§ããªãããã«ã³ãŒããã³ã³ãã€ã«ãããªãçç±ãç解ããããšããŠã5åã倱ããŸãã
ããªãã®äŸã¯ãFlutterã®StatelessWidgetãšStateã©ã€ããµã€ã¯ã«APIã®å®éã®åé¡ã§ã¯ãªãããããã€ããŒãã©ãã»ã©åé·ã§ããããã¹ãŠã«AliExpressWidgetsãæªçšããããšãæªãããšã§ããçç±ã®ã·ã§ãŒã±ãŒã¹ã§ãã
@rrousselGitã¯ã£ããããªãã£ããããããªããã ç§ãäžã§è¡ã£ãææ¡ã¯ãçŸå®çã§ã説æããŠããåé¡ã瀺ãããã©Flutterã¢ããªã±ãŒã·ã§ã³ïŒStatefulWidgetãªã©ã䜿çšïŒãäœæããããšã§ãããããã«ãããå®éã®å®å šãªã¢ããªã±ãŒã·ã§ã³ã«åºã¥ããŠææ¡ãè¡ãããšãã§ããŸãã ããã§èª¬æãããfetchUserãã®äŸãªã©ã®å ·äœçãªäŸã¯ãåžžã«ããã®ãããªã±ãŒã¹ãåŠçã§ããåçŽã§ããã¯ãå¿ èŠãšããªãããšããæ¹éã§è°è«ãããŠããŸããã ããŸããããã¯åçŽåãããããŠããŸããçŸå®ã®äžçã§ã¯ããã¯ãå¿ èŠã§ããã ã€ãŸããç§ã®ãã€ã³ãã¯ãããã¯ãæ¬åœã«å¿ èŠãªå®äžçã®äŸãäœæããŸããããããã¯ãé床ã«åçŽåãããŠããããã³ãŒãã®åå©çšã®é£ããã瀺ããŠããŸããããã«ãããæ°ããã³ãŒãã䜿çšããã«ãããã®åé¡ãåé¿ã§ãããã©ããã確èªã§ããŸãã ããŸãã¯æ°ããã³ãŒããå¿ èŠãªå ŽåããããŠåŸè ã®å Žåãããã¯ã®ãããªåœ¢ã«ããå¿ èŠããããã©ããããŸãã¯ããã«è¯ã解決çãèŠã€ããããšãã§ãããã©ããã
åå©çšå¯èœã§ããå¿ èŠãããã人ã ãåç §ãããç¶æ ããžãã¯ããäœã§ãããããç解ããŠããŸããã
ãã£ããã
ç¶æ
ããžãã¯ãšäžŠè¡ããã®ã¯ãUIããžãã¯ãšããŠã£ãžã§ãããããŒãã«ã«ãããããã®ã§ãã
ãŠã£ãžã§ããã¬ã€ã€ãŒãæè¡çã«åé€ããããšãã§ããŸãã ãã®å Žåãæ®ã£ãŠããã®ã¯RenderObjectsã§ãã
ããšãã°ãããããªã¹ãã«ãŠã³ã¿ãŒãäœæã§ããŸãã
var counter = 0;
final counterLabel = RenderParagraph(
TextSpan(text: '$counter'),
textDirection: TextDirection.ltr,
);
final button = RenderPointerListener(
onPointerUp: (_) {
counter++;
counterLabel.text = TextSpan(text: '$counter');
},
child: counterLabel,
);
ããã¯å¿
ãããè€éã§ã¯ãããŸããã ããããããã¯ãšã©ãŒãçºçããããã§ãã counterLabel
ã¬ã³ããªã³ã°ã«éè€ããããŸã
ãŠã£ãžã§ããã䜿çšãããšã次ã®ããšãã§ããŸãã
class _CounterState exends State {
int counter = 0;
Widget build(context ) {
return GestureDetector(
onTap: () => setState(() => counter++);
child: Text('$counter'),
);
}
}
ãããè¡ã£ãå¯äžã®ããšã¯ã宣èšåã«ããããšã«ãã£ãŠText
ããžãã¯ãå æ°å解ããããšã§ãã
ããããªã¹ãã®å€æŽã§ãã ãããã倧èŠæš¡ãªã³ãŒãããŒã¹ã§ã¯ãããã¯å€§å¹
ãªç°¡çŽ åã§ãã
ããã¯ã¯ãŸã£ããåãããšãããŸãã
ãã ãã Text
代ããã«ãç¶æ
ããžãã¯ã®ã«ã¹ã¿ã ããã¯ãååŸããŸãã ããã«ã¯ããªã¹ããŒããããŠã³ã¹ãHTTPãªã¯ãšã¹ãã®äœæãªã©ãå«ãŸããŸãã
ããªãã®äŸã¯ãFlutterã®StatelessWidgetãšStateã©ã€ããµã€ã¯ã«APIã®å®éã®åé¡ã§ã¯ãªãããããã€ããŒãã©ãã»ã©åé·ã§ããããã¹ãŠã«AliExpressWidgetsãæªçšããããšãæªãããšã§ããçç±ã®ã·ã§ãŒã±ãŒã¹ã§ãã
ããã¯ãããã€ããŒãšã¯é¢ä¿ãããŸããïŒãã®ã³ãŒãã¯çµå±ãããã€ããŒã䜿çšããŸããïŒã
ã©ã¡ãããšããã°ããããã€ããŒã¯context.watch
代ããã«Consumer
context.watch
æã£ãŠããã®ã§ãããè¯ãã§ãã
æšæºçãªè§£æ±ºçã¯ã Consumer
ãValueListenableBuilder
ã«çœ®ãæããããšã§ããããã«ããããŸã£ããåãåé¡ãçºçããŸãã
@Hixieã«åæããŸãããã©ãã¿ãŒã ãã®å Žåãšããã¯ã䜿çšããå Žåã®æå¹æ§ãå€æããã«ã¯ã2ã€äžŠã¹ãŠæ¯èŒããå¿ èŠããããšæããŸãã ããã¯ãããã¯ãåªããŠãããã©ãããä»ã®äººã«çŽåŸãããã®ã«ã圹ç«ã¡ãŸããããã©ã¢ããªããã®3çªç®ã®ãœãªã¥ãŒã·ã§ã³ã§æ§ç¯ãããŠããå Žåã¯ãå¥ã®ãœãªã¥ãŒã·ã§ã³ãããã«åªããŠããå¯èœæ§ããããŸãã ãã®ããã©ã¢ããªã®ã³ã³ã»ããã¯ãã°ããåããååšããŠããã
@satvikpendem
åãã§ãæäŒããããŠããã ããŸãã
flutter_hooks
ãªããžããªã®ãµã³ãã«ã¢ããªã¯ãããããããã€ãã®ç°ãªãããã¯ãšãããããç°¡åã«ãããã®/ãããã解決ããåé¡ã瀺ããŠãããšæããŸããããã¯è¯ãåºçºç¹ã«ãªãã§ãããã
ãŸãããã®å·ã§çŽ¹ä»ãããŠããããã€ãã®äŸãšã¢ãããŒãã䜿çšã§ãããšæããŸãã
æŽæ°ïŒã³ãŒãã¯ãã¡ãã httpsïŒ//github.com/TimWhiting/local_widget_state_approaches
ãªããžããªã®é©åãªååãããããªãã®ã§ããããç§ãã¡ã解決ããããšããŠããåé¡ã§ãããšæã蟌ãŸãªãã§ãã ããã ã¹ããŒããã«ãšããã¯ã§åºæ¬çãªã«ãŠã³ã¿ãŒã¢ããªãäœæããŸããã ä»å€ã¯ããŸãæéããããŸããããåé¡ã®å¯èœæ§ãããå
·äœçã«ç€ºããŠãŒã¹ã±ãŒã¹ãããã«è¿œå ããããšæããŸãã è²¢ç®ãããæ¹ã¯ãã¢ã¯ã»ã¹ããªã¯ãšã¹ãããŠãã ããã
ããã§èª¬æãããfetchUserãã®äŸãªã©ã®å ·äœçãªäŸã¯ãåžžã«ããã®ãããªã±ãŒã¹ãåŠçã§ããåçŽã§ããã¯ãå¿ èŠãšããªãããšããæ¹éã§è°è«ãããŠããŸããã ããŸããããã¯åçŽåãããããŠããŸããçŸå®ã®äžçã§ã¯ããã¯ãå¿ èŠã§ããã
åæããŸããã ç§ã¯ãã®ãããªãããªãã¯ãã®ãããªã±ãŒã¹ãæ±ãããšãã§ããããèŠãããšããªããšæããçµæã®ã³ãŒããããã¯ããªã¢ã³ããããåªããŠããããšã«åæããŸããã
ãã£ãšç§ã®ãã€ã³ãã¯ãç§ãã¡ãå¥ã®æ¹æ³ã§ç©äºãè¡ãããšã¯ã§ããŸãããçµæãšããŠåŸãããã³ãŒãã¯ãšã©ãŒãçºçãããããããã³/ãŸãã¯èªã¿ã«ãããªããšããããšã§ããã
ããã¯fetchUser
ãåœãŠã¯ãŸããŸã
ããã¯ã¯ãŸã£ããåãããšãããŸãã
ãã ããText
代ããã«ãç¶æ ããžãã¯ã®ã«ã¹ã¿ã ããã¯ãååŸããŸãã ããã«ã¯ããªã¹ããŒããããŠã³ã¹ãHTTPãªã¯ãšã¹ãã®äœæãªã©ãå«ãŸããŸãã
ãããããã®äžè¬çãªç¶æ ããžãã¯ãã©ãããã¹ããã¯ãŸã ããããŸããã ã€ãŸãããinitState / didUpdateDependencyãã¡ãœããã§ããŒã¿ããŒã¹ããèªã¿åããŠã£ãžã§ããããããããããŸããããŸã£ããåãã¯ãšãªãå®è¡ãã2ã€ã®ãŠã£ãžã§ãããèŠã€ãããªãããããããžãã¯ãã¯åãã§ã¯ãããŸããã
HTTPãªã¯ãšã¹ãã®äœæäŸã䜿çšããŸãã äžéšã®ãŠã£ãžã§ããã䜿çšããå¿ èŠã®ãããmakeHTTPRequestïŒurlãparamtersïŒãããµãŒãã¹ã¯ã©ã¹ã®ã©ããã«ãããšãããšãå¿ èŠãªãšãã«ã¡ãœãããçŽæ¥åŒã³åºãã®ã§ã¯ãªããããã¯ã䜿çšããã®ã¯ãªãã§ããïŒ ãã®å Žåãããã¯ã®äœ¿çšã¯ãã¬ãŒã³ã¡ãœããåŒã³åºããšã©ã®ããã«ç°ãªããŸããïŒ
ãªã¹ããŒã åãããšãèããŠãããŠã£ãžã§ããã¯ãããŸããã ç§ã®åãŠã£ãžã§ããã¯ãå¿ èŠãªãã®ããã¹ãŠãµãã¹ã¯ã©ã€ããããµãã¹ã¯ã©ã€ãã解é€ãã責任ããããŸãã ããã¯ã¯ã»ãšãã©ã®å Žåæ§æç³è¡£æ§æã§ããå¯èœæ§ããããŸãããç§ã®ãŠã£ãžã§ããã¯ãªããžã§ã¯ãã®åãçµã¿åããããªãã¹ã³ããªããããããã¯ã¯äœããã®æ¹æ³ã§ããã©ã¡ãŒã¿ãŒåãããå¿ èŠããããŸãã ç¹°ãè¿ããŸãããããã¯ã¯æãªããã®é¢æ°ãšã©ãéãã®ã§ããïŒ
ããã¯ãããã€ããŒãšã¯é¢ä¿ãããŸããïŒãã®ã³ãŒãã¯çµå±ãããã€ããŒã䜿çšããŸããïŒã
ã©ã¡ãããšããã°ããããã€ããŒã¯context.watch
代ããã«Consumer
context.watch
æã£ãŠããã®ã§ãããè¯ãã§ãã
ã¯ïŒ ãChatScreenãHookWidgetã解決ããããšã«ãªã£ãŠããããšã«å¯ŸããåäŸã¯æ¬¡ã®ãšããã§ãã
<strong i="19">@override</strong>
Widget build(BuildContext context) {
return Consumer<Auth>(
provider: authProvider,
builder: (context, auth, child) {
return Consumer<int>(
provider: selectedChatProvider,
builder: (context, chatId, child) {
ããã¯ãããã€ããŒãšã©ã®ããã«é¢ä¿ããããŸãããïŒ ããããããŸããã ç§ã¯ãããã€ããŒã®å°é家ã§ã¯ãããŸããããããã¯ééããªããããã€ããŒã䜿çšããã³ãŒãã®ããã§ãã
ãã®åé¡ã¯è€éãªåœå®¶ã«é¢ãããã®ã§ã¯ãªããšããäºå®ã䞻匵ããããšæããŸãã
ããã¯ãã³ãŒãããŒã¹å
šäœã«é©çšã§ããå°ããªå¢åã§ãã
ããã«ç€ºããäŸã®å€ã«åæã§ããªãå ŽåãStatefulWidgetã§å®è¡ã§ããªãããã¯ã§å®è¡ã§ããããšã¯äœããªããããã¢ããªã±ãŒã·ã§ã³ã¯äŒè©±ã«äœããããããŸããã
代ããã«ã ImplicitFetcher
ãããªãã€ã¯ãã¹ããããã䞊ã¹ãŠæ¯èŒãã枬å®å¯èœãªã¡ããªãã¯ã䜿çšããŠã©ã®ã³ãŒããåªããŠãããã_客芳çã«_å€æããããŸããŸãªå°ããªã¹ããããã«å¯ŸããŠãããè¡ãããšããå§ãããŸãã
ããã¯ãããã€ããŒãšã©ã®ããã«é¢ä¿ããããŸãããïŒ ããããããŸããã ç§ã¯ãããã€ããŒã®å°é家ã§ã¯ãããŸããããããã¯ééããªããããã€ããŒã䜿çšããã³ãŒãã®ããã§ãã
ãã®ã³ãŒãã¯ãããã€ããŒããã®ãã®ã§ã¯ãªããAttachedWidgetsã䜿çšããªãå¥ã®ãããžã§ã¯ãããã®ãã®ã§ãã
ãããã€ããŒã®Consumer
ã¯provider
ãã©ã¡ãŒã¿ãŒããããŸããã
ãããŠãç§ãè¿°ã¹ãããã«ã Consumer
-> ValueListenableBuilder / StreamBuilder / BlockBuilder / Observer / ..ã眮ãæããããšãã§ããŸãã
ãinitState / didUpdateDependencyãã¡ãœããã«ãããŸããããŸã£ããåãã¯ãšãªãå®è¡ãã2ã€ã®ãŠã£ãžã§ãããèŠã€ãããªãããããããžãã¯ãã¯åãã§ã¯ãããŸããã
åå©çšãããç¶æ ããžãã¯ã¯ããã¯ãšãªãäœæãããã§ã¯ãªãããxãå€æŽããããšãã«äœããå®è¡ãããã§ãã ãäœãããããã¯å€ãããããããŸãããããxãå€ãããšããã¯äžè¬çã§ã
å
·äœäŸïŒ
ãŠã£ãžã§ãããåãåãIDãå€æŽããããã³ã«ããŠã£ãžã§ãããHTTPãªã¯ãšã¹ããè¡ãããã«ãããå ŽåããããŸãã
ãŸãã package:async
ã®CancelableOperationã䜿çšããŠãä¿çäžã®ãªã¯ãšã¹ãããã£ã³ã»ã«ããããšæããŸãã
ããã§ããŸã£ããåãããšãå®è¡ãããããHTTPãªã¯ãšã¹ããç°ãªã2ã€ã®ãŠã£ãžã§ããããããŸãã
æåŸã«ã次ã®ããã«ãªããŸãã
CancelableOperation<User> pendingUserRequest;
initState() {
pendingUserRequest = fetchUser(widget.userId);
}
didUpdateWidget(oldWidget) {
if (widget.userId != oldWidget.userId) {
pendingUserRequest.cancel();
pendingUserRequest = fetchUser(widget.userId);
}
}
dispose() {
pendingUserRequest.cancel();
}
VSïŒ
CancelableOperation<Message> pendingMessageRequest;
initState() {
pendingMessageRequest = fetchMessage(widget.messageId);
}
didUpdateWidget(oldWidget) {
if (widget.userId != oldWidget.messageId) {
pendingMessageRequest.cancel();
pendingMessageRequest = fetchMessage(widget.messageId);
message = pendingMessageRequest.value;
}
}
dispose() {
pendingMessageRequest.cancel();
}
å¯äžã®éãã¯ã fetchUser
ãfetchMessage
ã§ãã ãã以å€ã®ããžãã¯ã¯100ïŒ
åãã§ãã ãã ããåå©çšã§ããªãããããšã©ãŒãçºçãããããªããŸãã
ããã¯ã䜿çšãããšããããuseUnaryCancelableOperation
ããã¯ã«å解ã§ããŸãã
ã€ãŸããåã2ã€ã®ãŠã£ãžã§ããã䜿çšãããšã代ããã«æ¬¡ã®ããã«ãªããŸãã
Widget build(context) {
Future<User> user = useUnaryCancelableOperation(userId, fetchUser);
}
VS
Widget build(context) {
Future<Message> message = useUnaryCancelableOperation(messageId, fetchMessage);
}
ãã®ã·ããªãªã§ã¯ããªã¯ãšã¹ãã®äœæãšãã£ã³ã»ã«ã«é¢é£ãããã¹ãŠã®ããžãã¯ãå
±æãããŸãã fetchUser
ãšfetchMessage
ãšããæå³ã®ããéãã ããæ®ã£ãŠããŸãã
ãã®useUnaryCancelableOperation
ããããã±ãŒãžãäœæããããšãã§ããä»ã§ã¯èª°ããèªåã®ã¢ããªã§ãããåå©çšã§ããŸãã
ããã«ç€ºããäŸã®å€ã«åæã§ããªãå ŽåãStatefulWidgetã§å®è¡ã§ããªãããã¯ã§å®è¡ã§ããããšã¯äœããªããããã¢ããªã±ãŒã·ã§ã³ã¯äŒè©±ã«äœããããããŸããã
ãããæ¬åœãªããç§ãã¡ã¯ãã®ãã°ãéããã¹ãã ãšæããŸãããªããªããããã§äžããããäŸã«ã€ããŠã¯ãã§ã«è°è«ããŠããŠããããã¯èª¬åŸåããªãããã§ãã ããããç§ã¯æ¬åœã«ç¶æ³ãããããç解ããããšæããŸãããã®ãã°ã®ä»¥åã®ã³ã¡ã³ããããå©ç¹ã¯ã¢ããªã±ãŒã·ã§ã³ã¬ãã«ã«ããããã«èãããã®ã§ãã¢ããªã±ãŒã·ã§ã³ã®äŸãæ€èšããããšããå§ãããŸãã
å¯äžã®éãã¯ã
fetchUser
ãfetchMessage
ã§ãã ãã以å€ã®ããžãã¯ã¯100ïŒ åãã§ãã ãã ããåå©çšã§ããªãããããšã©ãŒãçºçãããããªããŸãã
ãšã©ãŒãçºçãããããã®ãšãåå©çšã§ãããã®ã¯äœã§ããïŒ æœè±¡åãšã¯ã©ã¹éå±€ã®ãŸã£ããæ°ããã¬ã€ã€ãŒãå®è£ ããããšã§ãã¯ã©ã¹ã«3ã€ã®ã¡ãœãããå®è£ ããå¿ èŠããªããªããããéãã«ãªããŸãã
ç¹°ãè¿ããŸãããäœããäžè¬çãªãã¿ãŒã³ã§ãããããšãã£ãŠãããã«å¯ŸããŠæ°ããæ©èœãäœæããå¿ èŠããããšããæå³ã§ã¯ãããŸããã ããã«ããã®å Žåã«ç¹°ãè¿ãçºçããã³ãŒããæžããããå Žåã¯ãStatefulWidget *ã¯ã©ã¹ãæ¡åŒµããinitstate / didUpdateWidgetã¡ãœãããå ±éãããã§ãªãŒããŒã©ã€ãã§ããŸãã
ããã¯ã䜿çšãããšãããã
useUnaryCancelableOperation
ããã¯ã«å解ã§ããŸããã€ãŸããåã2ã€ã®ãŠã£ãžã§ããã䜿çšãããšã代ããã«æ¬¡ã®ããã«ãªããŸãã
Widget build(context) { Future<User> user = useUnaryCancelableOperation(userId, fetchUser); }
VS
Widget build(context) { Future<Message> message = useUnaryCancelableOperation(messageId, fetchMessage); }
ãã®ã·ããªãªã§ã¯ããªã¯ãšã¹ãã®äœæãšãã£ã³ã»ã«ã«é¢é£ãããã¹ãŠã®ããžãã¯ãå ±æãããŸãã
fetchUser
ãšfetchMessage
ãšããæå³ã®ããéãã ããæ®ã£ãŠããŸãã
ãã®useUnaryCancelableOperation
ããããã±ãŒãžãäœæããããšãã§ããä»ã§ã¯èª°ããèªåã®ã¢ããªã§ãããåå©çšã§ããŸãã
ç³ãèš³ãããŸããããããã¯ç§ããã¯ééããªã倧ããããšã§ã¯ãããŸããã ããããªã³ãŒãåé·æ§ããç¯çŽã§ããªããšããäºå®ãé€ãã°ãæŠå¿µçã«ãinitStateãããã³ãupdateãã©ã€ããµã€ã¯ã«ã¡ãœããã«å±ããã³ãŒãããã«ãã¡ãœããã«ããã¡ã¯ã¿ãªã³ã°ãããããšã¯å€§ããããšã§ã¯ãããŸããã
ç§ã®ãã«ãã¡ãœããã¯ãã¬ã€ã¢ãŠãã®ã¿ããã«ãããä»ã«ã¯äœããã«ãããªãããšãæåŸ ããŠããŸãã äŸåé¢ä¿ã®èšå®ãšç Žæ£ã¯ãbuildã¡ãœããã«ã¯çµ¶å¯Ÿã«å±ããŠããŸãããåãã¿ã€ãã®ã³ãŒããæ瀺çã«æžãçŽããŠãå°æ¥ã®èªåãä»ã®äººã«ãŠã£ãžã§ããã®åäœãæ瀺çã«ããå¿ èŠãããããšãéåžžã«å¬ããæããŸãã ãããŠãbuildã¡ãœããã«ãã¹ãŠã貌ãä»ããªãããã«ããŸãããã
ãããæ¬åœãªããç§ãã¡ã¯ãã®ãã°ãéããã¹ãã ãšæããŸã
@Hixieããªãã§ãã ããã 人ã ã¯ãã®åé¡ãæ°ã«ããŸãã ç§ã¯åãããšã«ã€ããŠredditã§ããªããšè©±ããŸããããSwiftUIã®ã³ã³ããã¹ãã§ïŒ https ïŒ
ããã¯ããã¯ã§ã¯ãªããã¹ããŒããã«ãŠã£ãžã§ãããäœããã®åœ¢ã§æ¹åããããšã§ãã 人ã ã¯åã«å®åæãæžãããšãå«ããŸãã ãã¥ãŒã®ã»ãã³ãã£ã¯ã¹ãRAIIããã³ã³ããŒããããšã«æ £ããŠããSwiftUIã³ãŒããäœæããéçºè ã«ãšã£ãŠããã£ã¹ããŒã¶ãã«ãæåã§ç®¡çããããšã¯ããŸã£ããåé¡ã®ããã«æãããŸãã
ã ããç§ã¯ãã©ãã¿ãŒããŒã ã«å°ãªããšããããåé¡ãšèŠãªãã代æ¿ã®è§£æ±ºç/æ¹åã«ã€ããŠèããããšããå§ãããŸãã
ç§ã®ãã«ãã¡ãœããã¯ãã¬ã€ã¢ãŠãã®ã¿ããã«ãããä»ã«ã¯äœããã«ãããªãããšãæåŸ ããŠããŸãã äŸåé¢ä¿ã®èšå®ãšç Žæ£ã¯ããã«ãã¡ãœããã«å«ãŸããŠããŸããã
ãããéèŠãªãã€ã³ãã§ãã ãã«ãã¡ãœããã¯çŽç²ã§ããå¿ èŠããããŸãã ããã§ãç§ã¯ç§ãã¡ãå°é£ãªãã§å©ç¹ãåŸãããšãã§ããã°ããã®ã«ãšæããŸãã
ç§ã¯ããã§ãã£ãšå€ãã®äŸãæšãé²ããããšãæ¬åœã«ç解ããŠããŸããã ããã¯ãã®é¡ã«æããã§ãã
ããã¯ã«ãã£ãŠè§£æ±ºãããåé¡ã¯åçŽæå¿«ã§ãããã³ãŒããDRYã«ä¿ã¡ãŸãã ããã®å©ç¹ã¯ãæãããªãã®ãã³ãŒãã®æžå°==ãã°ã®æžå°ãã¡ã³ããã³ã¹ã®å®¹æãããã°ãé ãå Žæã®æžå°ãå šäœçãªè¡æ°ã®æžå°ãèªã¿ãããã®åäžããžã¥ãã¢ããã°ã©ããŒã®æç±æ§ã®åäžãªã©ã§ãã
å®éã®ãŠãŒã¹ã±ãŒã¹ã«ã€ããŠè©±ããŠããå Žåãããã¯ã12ã®ç°ãªããã¥ãŒã§12ã®ã¢ãã¡ãŒã¿ãŒã³ã³ãããŒã©ãŒãæ¯åã»ããã¢ããããã³ç Žæ£ããdisposeïŒïŒåŒã³åºããèŠéããããäžéšããªãŒããŒã©ã€ããããããã¢ããªã§ããä»ã®ã©ã€ããµã€ã¯ã«æ¹æ³ã 次ã«ããããä»ã®æ°åã®ã¹ããŒããã«ã€ã³ã¹ã¿ã³ã¹ã«é©çšãããšãæ°çŸãŸãã¯æ°åã®ç¡æå³ãªã³ãŒãè¡ãç°¡åã«ç¢ºèªã§ããŸãã
Flutterã¯ãå°ããªãªããžã§ã¯ãã®ç¶æ ã絶ããç¹°ãè¿ããèšå®ããç Žæ£ããå¿ èŠããããããã®ã±ãŒã¹ã§ãã£ã±ãã§ããããã«ãããååšããå¿ èŠã®ãªããã°ã®ããããçš®é¡ã®æ©äŒãçãŸããŸãããçŸåšããã®ããŒãã»ããã¢ãã/ãã£ã¢ããŠã³/åæããžãã¯ãå ±æããŸãã
ãã®åé¡ã¯ãã»ããã¢ãããšãã£ã¢ããŠã³ã®ãã§ãŒãºãããããŸãã¯åžžã«çµã³ä»ããå¿ èŠã®ããã©ã€ããµã€ã¯ã«ããã¯ããããæåéã_any_ç¶æ ã§ç¢ºèªã§ããŸãã
ç§èªèº«ããŠã£ãžã§ããã䜿çšããã®ãæåã®ã¢ãããŒãã ãšæããŸããããšãã°ãã»ããã¢ãã/ãã£ã¢ããŠã³ãéåžžã«ç ©ããããåé·ã§ãã°ãçºçãããããããAnimatorControllerã䜿çšããããšã¯ãã£ãã«ãããŸããã代ããã«ãå¯èœãªéãTweenAnimationBuilderã䜿çšããŸãã ãã ãããã®ã¢ãããŒãã«ã¯ãç¹å®ã®ãã¥ãŒã§ã¹ããŒããã«ãªããžã§ã¯ãã®æ°ãå¢ãããšå¶éããããå®éã«ã¯äœãå¿ èŠãšãããªãå Žæã«ãã¹ããšåé·æ§ã匷å¶ãããŸãã
@szotpç§ã¯ããŠããŸãã...解決çãè©äŸ¡ã§ããããã«ãåé¡ã瀺ã1ã€ä»¥äžã®ããŒã¹ã©ã€ã³ã¢ããªã確ç«ããããšæããŸãã ç§ã¯èªåã§ããããšæã£ãŠããŸãããç§ãã¡ãäœã解決ããããšããŠããã®ãæ£ç¢ºã«ã¯ããããªãã®ã§ãç§ã¯ãããããã®ã¯ééã£ã人ã§ãã
@escamoteurããŒã¹ã©ã€ã³ã¢ããªã¯ãåé¡ã®ãªããœãªã¥ãŒã·ã§ã³ãèšèšããã®ã«åœ¹ç«ã¡ãŸãã
@esDotDevãããŸã§ãã®ãã°ã§ãã®ãããªã±ãŒã¹ã«ã€ããŠèª¬æããŠããŸããããããã¯ä»¥å€ã®ãœãªã¥ãŒã·ã§ã³ã¯ããœãªã¥ãŒã·ã§ã³ã察åŠããäŸã«å«ãŸããŠããªãåé¡ã解決ããªããããæ¯ååŽäžãããŸãã ãããã£ãŠãåé¡ã®ç°¡åãªèª¬æã§ã¯ãå®å šãªç¯å²ãææ¡ããã®ã«ååã§ã¯ãªãããã§ãã ããšãã°ãã12åã®ã¢ãã¡ãŒã¿ãŒã³ã³ãããŒã©ãŒãã®å Žåã¯ãã¢ãã¡ãŒã·ã§ã³ã³ã³ãããŒã©ãŒã®é åãšDartã®æ©èœæ©èœã«ãã£ãŠè§£æ±ºã§ããå¯èœæ§ããããŸãã TweenAnimationBuilderã¯å¥ã®è§£æ±ºçãããããŸããã ãããã®ã©ã¡ããããã¯ãå«ã¿ãŸããã ããããç§ãææ¡ããå Žåã誰ããç§ãèŠéããããšãææãããããã¯...ã®ããã«æ©èœããªãããšèšã£ãŠããã®ïŒäŸã®æèã§ã¯æ°ããïŒåé¡ãæèµ·ãããšç¢ºä¿¡ããŠããŸãã ãããã£ãŠãç§ãã¡å šå¡ãåæããããŒã¹ã©ã€ã³ã¢ããªã®å¿ èŠæ§ã¯ãåé¡ã®å®å šãªåºãããã«ããŒããŸãã
誰ãããããåé²ããããã®ãªããç§ã¯ãããè¡ãããã®æè¯ã®æ¹æ³ã¯ç§ãäžã§èª¬æãããã®ã ãšæ¬åœã«æããŸãïŒhttps://github.com/flutter/flutter/issues/51752#issuecomment-670249755ãšhttps://github.com / flutter / flutter / issues / 51752ïŒissuecomment-670232842ïŒã ããã¯ç§ãã¡å šå¡ã解決ããããšããŠããåé¡ã®ç¯å²ãè¡šãããšã«åæã§ããåºçºç¹ãç§ãã¡ã«äžããã§ãããã ãããŠãç§ãã¡ã¯ãœãªã¥ãŒã·ã§ã³ãèšèšããããšãã§ãããã®ã¢ãã¬ã¹ã®ã¢ãã¬ã¹ãã¹ãŠã®æ¬²æïŒäŸãã°@rrousselGitã®åå©çšã®ããã®å¿ èŠæ§ã@Rudikszãã¯ãªãŒã³ãã«ãæ¹æ³ã«ã€ããŠã®å¿ èŠæ§ããªã©ïŒããããŠãæãéèŠãªã®ã¯æã ããããã®ãœãªã¥ãŒã·ã§ã³ãè©äŸ¡ã§ãããšããæ¹æ³ã§ãããã®åé¡ããŒã¹ã©ã€ã³ã¢ããªã®ã³ã³ããã¹ãã
ç§ãã¡ã¯çã圌ã®åé¡ã«ããªãç°¡åã«åæã§ãããšæããŸãã
_StreamsãAnimatorControllersãªã©ã«é¢é£ããã»ããã¢ãã/ãã£ã¢ããŠã³ã¿ã¹ã¯ãå
±æãããšã¬ã¬ã³ããªæ¹æ³ã¯ãããŸãããããã«ãããäžèŠãªåé·æ§ããã°ã®å¯èœæ§ãèªã¿ãããã®äœäžã«ã€ãªãããŸãã_
誰ããããã«åæããŸãããïŒ ããããå§ããŠã解決çãæ¢ããŠåé²ããããšã¯ã§ããŸãããïŒ ãããæåã«äžå¿çãªåé¡ã§ããããšã«åæããå¿ èŠããããŸããããŸã ããã§ã¯ãªãããã§ãã
ç§ããããæžããŠãããšããç§ã¯åé¡ã®ååãšå®å
šã«äžèŽããŠããããšã«æ°ã¥ããŸãããããã¯èªç±åœ¢åŒã§ãããè°è«ã®äœå°ããããŸãã
ãç¶æ
ããžãã¯ã®åå©çšã¯ãåé·ãããããé£ããããã
ç§ã«ãšã£ãŠãããã¯éåžžã«æçœãªåé¡ã§ãããç§ãã¡ã¯ããã«èšè«ã®æ®µéãéããŠãäœãããŸããããã«ã€ããŠãã¬ã€ã³ã¹ããŒãã³ã°ã«ç§»ãã¹ãã§ãã åå©çšå¯èœãªãã€ã¯ãã¹ããŒããå¿ èŠã§ã...äœããç解ã§ãããšç¢ºä¿¡ããŠããŸãã ããã¯æ¬åœã«äžæ¥ã®çµããã«å€ãã®Flutterãã¥ãŒãã¯ãªãŒã³ã¢ããããããããããå ç¢ã«ããã§ãããã
@Hixieããªãã§ãã ããã 人ã ã¯ãã®åé¡ãæ°ã«ããŸãã ç§ã¯åãããšã«ã€ããŠredditã§ããªããšè©±ããŸããããSwiftUIã®ã³ã³ããã¹ãã§ïŒ https ïŒ
SwiftUIã®äŸã¯ãStatefulWidgetã¯ã©ã¹ãæ¡åŒµããã ãã§ãæ°è¡ã®ã³ãŒãã§dartã«è€è£œã§ããŸãã
éç¥æ©èœããµãã¹ã¯ã©ã€ãããããå€éšåŒã³åºããè¡ã£ããããªãStatefulWidgetsããããŸãããå®éããããã®ã»ãšãã©ã¯ãã®ãããªãã®ã§ãã ç§ã¯çŽ100åã®ã«ã¹ã¿ã ãŠã£ãžã§ãããæã£ãŠããŸãïŒãã¹ãŠãã¹ããŒããã«ãšããããã§ã¯ãããŸãããïŒããããã15åã¯ãããã®äŸã§èª¬æãããŠããããã«ãããããçš®é¡ã®ãå ±éç¶æ ããžãã¯ããæã£ãŠããŸãã
é·æçã«ã¯ãäžå¿ èŠãªãªãŒããŒããããåé¿ããããã«ãæ°è¡ã®ã³ãŒãïŒãã€ã©ãŒãã¬ãŒããšãåŒã°ããŸãïŒãèšè¿°ããããšã¯å°ããªãã¬ãŒããªãã§ãã ç¹°ãè¿ãã«ãªããŸãããinitState / didUpdateã¡ãœãããå®è£ ããå¿ èŠããããšãããã®åé¡ã¯ãããªãèªåŒµãããŠããããã§ãã ããã§èª¬æãããã¿ãŒã³ã®ããããã䜿çšãããŠã£ãžã§ãããäœæããå Žåãã©ã€ããµã€ã¯ã«ã¡ãœããã®ãå®è£ ãã«æåã®5ã10åãè²»ããã次ã«ã©ã€ããµã€ã¯ã«ã¡ãœããã«è§Šããã«ãŠã£ãžã§ããèªäœãå®éã«äœæããŠç£šãã®ã«æ°æ¥ãè²»ãããŸãã ãããããã€ã©ãŒãã¬ãŒãã®ã»ããã¢ãã/å解ã³ãŒãã®èšè¿°ã«è²»ããæéã¯ãç§ã®ã¢ããªã³ãŒããšæ¯èŒããŠãããããã§ãã
ç§ãèšã£ãããã«ãStatefulWidgetsãäœã®ããã«äœ¿çšããããã«ã€ããŠã»ãšãã©ä»®å®ãããªããšããäºå®ã¯ãããããéåžžã«åŒ·åã§å¹ççã«ãããã®ã§ãã
ãã®ç¹å®ã®ãŠãŒã¹ã±ãŒã¹ã®ããã«StatefulWidgetããµãã¯ã©ã¹åããïŒãŸãã¯ããªãïŒæ°ããã¿ã€ãã®ãŠã£ãžã§ãããFlutterã«è¿œå ããããšã¯åé¡ãããŸããããStatefulWidgetèªäœã«ãã€ã¯ããªãã§ãã ããã ãããã¯ãã·ã¹ãã ããã€ã¯ãã¹ããŒãã«äŒŽããªãŒããŒããããå¿ èŠãšããªããŠã£ãžã§ããããããããããŸãã
@esDotDevç§ã¯ãããäžéšã®äººã
ãçŽé¢ããŠããåé¡ã§ããããšã«åæããŸãã ç§ã¯ãã®å·ã®ååã§ããã€ãã®è§£æ±ºçãææ¡ããŸããïŒGitHubããã¹ãŠã®ã³ã¡ã³ãã衚瀺ããããšã奜ãŸãªãããã Property
ã¯ã©ã¹ã®ããŸããŸãªããŒãžã§ã³ãæ€çŽ¢ããŠãã ããã é£ããã®ã¯ããããã®ææ¡ãç¹å®ã®åé¡ã解決ããªãã£ãããã«åŽäžãããããšã§ãïŒããšãã°ãããå Žåã«ã¯ããããªããŒããåŠçãããå¥ã®å Žåã«ã¯didUpdateWidgetãåŠçããŸããã§ããïŒã ããã§ç§ã¯ããã«ææ¡ãããŸãããããããããããããã¯ä»ã®äœããåŠçããªãã£ãã®ã§åã³åŽäžãããŸããïŒç§ã¯äœãå¿ããŠããŸããïŒã ãã®ãããåé¡ã®è§£æ±ºçãèŠã€ããããšãã§ããããã«ãåé¡å
šäœãè¡šãããšã«åæããããçš®ã®ããŒã¹ã©ã€ã³ãçšæããããšãéèŠã§ãã
ç®æšã¯å€ãã£ãŠããŸããã ææ¡ããã解決çã«ã¯æè»æ§ãæ¬ ããŠãããšããæ¹å€ããããŸãã ãããã®ã©ãããããããå®è£ ãããã¹ããããã®å€ã§åäœãç¶ããŸããã
ãããããã®å·ã®ã¿ã€ãã«ããé£ããããšèšåããŠããçç±ã§ããçŸåšãåé¡ã解決ããæ¹æ³ã«æè»æ§ããªãããã§ãã
ãããèŠãå¥ã®æ¹æ³ã¯æ¬¡ã®ãšããã§ãã
ãã®åé¡ã¯åºæ¬çã«ãç¶æ
ããžãã¯çšã«ãŠã£ãžã§ããã¬ã€ã€ãŒãå®è£
ããå¿
èŠããããšäž»åŒµããŠããŸãã
ææ¡ããã解決çã¯ãããããRenderObjectsã§ãããè¡ãããšãã§ããŸããã§ãã
_é·æçã«ã¯ãæ°è¡ã®ã³ãŒãïŒãã€ã©ãŒãã¬ãŒããšãåŒã°ããŸãïŒãæžãããšã¯ãäžå¿ èŠãªãªãŒããŒããããåé¿ããããã®å°ããªãã¬ãŒããªãã§ãã_
ãã®å£°æãšã®ã«ããã«ã®ãããïŒ
Thing.DOTween()
ïŒã 15ã¯ã°ãããŠããŸãã@esDotDev
ç§ã«ãšã£ãŠãããã¯éåžžã«æçœãªåé¡ã§ãããç§ãã¡ã¯ããã«èšè«ã®æ®µéãéããŠãäœãããŸããããã«ã€ããŠãã¬ã€ã³ã¹ããŒãã³ã°ã«ç§»ãã¹ãã§ãã
ãŠã£ãžã§ããã®æ¡åŒµã ValueNotifierãChangeNotifierãæ¡åŒµããŠäžè¬çãªäœ¿çšãã¿ãŒã³ãåçŽåããæ¹æ³ãšåæ§ã«ã誰ããç¹å®ã®ãŠãŒã¹ã±ãŒã¹ã«åãããŠç¬èªã®StatelessWidgetsãäœæã§ããŸãã
ã¯ããç§ã¯ãããå¹æçãªã¢ãããŒãã§ããããšã«åæããŸãããããã¯æãŸãããã®ãæ®ããŸãã ã¢ãã¡ãŒã¿ãŒã1人ããå Žåã¯ãTweenAnimationBuilderã䜿çšã§ããŸãã ãã£ããããããã¯ãŸã 5è¡ã®ã³ãŒãã®ãããªãã®ã§ãããäœã§ãã§ãã ããã¯åäœããŸã...ããã»ã©æªãã¯ãããŸããã ããããç§ã2ã€ãŸãã¯3ã€æã£ãŠããå Žåã¯ã©ããªããŸããïŒ ä»ãç§ã¯å°çã«å ¥ãåã«ãªã£ãŠããŸããäœããã®çç±ã§cplã®ä»ã®ã¹ããŒããã«ãªããžã§ã¯ããããå Žåãããã¯ãã¹ãŠã¡ãã£ãšã€ã³ãã³ãã®æ··ä¹±ã«ãªãããã»ããã¢ãããæŽæ°ãå解ã®ã©ã³ãã ãªã³ã¬ã¯ã·ã§ã³ãã«ãã»ã«åããéåžžã«ç¹æ®ãªãŠã£ãžã§ãããäœæããŠããŸãè«çã
ãŠã£ãžã§ããã®æ¡åŒµã ValueNotifierãChangeNotifierãæ¡åŒµããŠäžè¬çãªäœ¿çšãã¿ãŒã³ãåçŽåããæ¹æ³ãšåæ§ã«ã誰ããç¹å®ã®ãŠãŒã¹ã±ãŒã¹ã«åãããŠç¬èªã®StatelessWidgetsãäœæã§ããŸãã
äžåºŠã«æ¡åŒµã§ããåºæ¬ã¯ã©ã¹ã¯1ã€ã ãã§ãã ããã¯ã¹ã±ãŒãªã³ã°ããŸãã
ããã¯ã¹ã€ã³ã¯æ¬¡ã®è«ççãªè©Šã¿ã§ãã ããããOPãèšåããŠããããã«ãããããã¹ã±ãŒãªã³ã°ããŸããã
@esDotDev
ãŸãã¯ãã»ããã¢ãããæŽæ°ãããã³ãã£ã¢ããŠã³ããžãã¯ã®ã©ã³ãã ãªã³ã¬ã¯ã·ã§ã³ãã«ãã»ã«åããéåžžã«ç¹æ®ãªãŠã£ãžã§ãããäœæããŠããŸãã
3ã4çš®é¡ã®AnimationControllerãèšå®ããå¿ èŠãããçš®é¡ã®ãŠã£ãžã§ããã¯ãéåžžã«ç¹æ®ãªãŠãŒã¹ã±ãŒã¹ã®ããã«èãããŸããèšå®/å解ããžãã¯ã®ã©ã³ãã ãªåéããµããŒãããããšã¯ããã¬ãŒã ã¯ãŒã¯ã®äžéšã§ãã£ãŠã¯ãªããŸããã å®éãinitState / didUpdateWidgetã¡ãœãããæåã«å ¬éãããŠããã®ã¯ãã®ããã§ãããã®ãããæãã®ãŸãŸã«ã»ããã¢ãããã©ã³ãã ã«åéã§ããŸãã
ç§ã®æé·ã®initStateã¡ãœããã¯5è¡ã®ã³ãŒãã§ããããŠã£ãžã§ããã¯é床ã®ãã¹ãã«æ©ãŸãããããšã¯ãªãã®ã§ãç§ãã¡ã¯ééããªãããŸããŸãªããŒãºãšãŠãŒã¹ã±ãŒã¹ãæã£ãŠããŸãã ãŸãã¯å¥ã®éçºã¹ã¿ã€ã«ã
@esDotDev
3.ããã¯ã®ãããªãã®ãšè©±ãåã䟡å€ã®ãããªãŒããŒãããã¯èŠåœãããŸããã ãªããžã§ã¯ãã®é åã«ã€ããŠè©±ããŠããã®ã§ãããããããã«å°æ°ã®fxnsããããŸãã ããŒãã§ã¯ãéåžžã«é«éã§ãã ããã¯èµ€ãã·ã³ã®ã€ã¢ã§ãã
ææ¡ããã解決çãflutter_hooksããã±ãŒãžã®ãããªãã®ã§ããå Žåãããã¯ãŸã£ããçå®ã§ã¯ãããŸããã ã¯ããæŠå¿µçã«ã¯é¢æ°ãå«ãé åã§ãããå®è£ ã¯ç°¡åã§ãå¹ççã§ããããŸããã
ã€ãŸããç§ã¯ééã£ãŠãããããããŸããããHookElementã¯ãç¬èªã®ãã«ãã¡ãœããã§èªåèªèº«ãåæ§ç¯ããå¿
èŠããããã©ããããã§ãã¯ããŠããããã§ãã
ãŸãããã¹ãŠã®ãŠã£ãžã§ãããã«ãã§ããã¯ãåæåãååæåããŸãã¯ç Žæ£ããå¿
èŠããããã©ããã確èªããããšã¯ãããªãã®ãªãŒããŒãããã®ããã«æãããŸãã æ°åãæªãã®ã§ãééã£ãŠãããšããã®ã§ããã
æ¯èŒã®ããã®ããŒã¹ã¢ããªãšããŠ@brianeganã®ã¢ãŒããã¯ãã£ã®äŸã®1ã€ãåãããšã¯çã«ããªã£ãŠããŸããïŒ
ããã§ä»å ¥ãããããããŸããããããããã§ã«èšããããã©ããã¯ããããŸããã ããããReactã§ã¯ãããã¯ã䜿çšããã©ã€ããµã€ã¯ã«ã«ã€ããŠã¯ããŸãèããŠããŸãããã³ã³ããŒãã³ã/ãŠã£ãžã§ããã®æ§ç¯ã«æ £ããŠãããšæãããã«èããããããããŸããããã©ã€ããµã€ã¯ã«ãããã»ã©éèŠã§ã¯ãªãçç±ã¯ããã«ãããŸãã
ã»ãšãã©ã®å Žåãå°éå ·ã«åºã¥ããŠå®è¡ããç¶æ ãŸãã¯ã¢ã¯ã·ã§ã³ã䜿çšããŠã³ã³ããŒãã³ã/ãŠã£ãžã§ãããæ§ç¯ããŠããå Žåããã®ç¶æ /å°éå ·ãå€æŽããããšãã«äœããçºçããå¿ èŠããããŸãïŒããšãã°ããã®ã¹ã¬ããã§èª¬æããããã«ãåå®è¡ããå¿ èŠããããŸã-userIdããããã£ãå€æŽããããšãã«ãŠãŒã¶ãŒã®è©³çŽ°ããã§ããããŸãïŒã éåžžããŠã£ãžã§ããã®ãã¹ãŠã®å°éå ·ãå€æŽããããšãã«çºçãããã®ã§ã¯ãªããuserIdã®å€æŽã®ãå¹æããšèããæ¹ãã¯ããã«èªç¶ã§ãã
ã¯ãªãŒã³ã¢ããã«ã€ããŠãåãã§ãããéåžžãããã¹ãŠã®ãããã/ç¶æ ãå€æŽããããšãã«Xãã¯ãªãŒã³ã¢ããããããšãå¿ããªãã§ãã ãããã³ã³ããŒãã³ãå šäœãç Žå£ããããšããã
ç§ã¯ãã°ããFlutterãæžããŠããªãã£ãã®ã§ããã®ã¢ãããŒããçŸåšã®Flutterã®èãæ¹ã«äžããçŸåšã®æ°åãå¶éãç¥ã£ãŠããããã«èãããããšã¯ããŠããŸãããç§ã¯ãããŸããŸãªæèŠãåãå ¥ããŠããŸãã ç§ã®èãæ¹ãã©ã€ããµã€ã¯ã«ãã©ãã€ã ã«æ·±ãæ ¹ä»ããŠããã®ã§ãReactããã¯ã«ç²ŸéããŠããªãå€ãã®äººã ãç§ã圌ãã«çŽ¹ä»ããããšããšåãæ··ä¹±ãæ±ããŠãããšæããŸãã
@escamoteur @Rudiksz @Hixieç§ãã¡ã¯ãããã®äŸãäœæãå§ããŠãããšããã«æåŸ ãããããšã@TimWhitingã«ãã£ãŠäœæãããGitHubã®ãããžã§ã¯ãããããŸããã åå人/ã°ã«ãŒãã¯ãäºåå®çŸ©ãããåé¡ãã©ã®ããã«è§£æ±ºããããäœæã§ããŸãã ãããã¯æ¬æ Œçãªã¢ããªã§ã¯ãªããããŒãžã®ãããªãã®ã§ãããããè€éãªäŸã瀺ãã®ã«åœ¹ç«ã€å Žåã¯ãã¢ããªãè¿œå ããããšãã§ããŸãã 次ã«ãåé¡ã«ã€ããŠè©±ãåããããåªããAPIãäœæã§ããŸãã @TimWhitingã¯ãç§ãæšæž¬ããèå³ã®ãã人ãªã誰ã§ãæåŸ ã§ããŸãã
@satvikpendem @TimWhitingããã¯çŽ æŽãããã§ãïŒ ããããšãããããŸããã
@esDotDev
éåžžã«å ·äœçãªãŠãŒã¹ã±ãŒã¹ã§ãããã»ããã¢ãã/ãã£ã¢ããŠã³ããžãã¯ã®ã©ã³ãã ãªåéããµããŒãããããšã¯ããã¬ãŒã ã¯ãŒã¯ã®äžéšã§ãã£ãŠã¯ãªããŸããã
ããã¯ãããã¯ãé ã«åœããéã§ãã åã¿ã€ãã®ãªããžã§ã¯ãã¯ãç¬èªã®ã»ããã¢ãããšå解ãæ åœããŸãã ã¢ãã¡ãŒã¿ãŒã¯ãã¹ããªãŒã ãªã©ãšåæ§ã«ãèªåèªèº«ãäœæãæŽæ°ãç Žæ£ããæ¹æ³ãç¥ã£ãŠããŸãã ããã¯ã¯ããã¥ãŒå šäœã«æ£åšããç¶æ ã¹ãã£ãã©ãŒã«ãã£ã³ã°ã®ãã©ã³ãã ã³ã¬ã¯ã·ã§ã³ãã®ãã®åé¡ãå ·äœçã«è§£æ±ºããŸãã ããã«ããããã¥ãŒã³ãŒãã®å€§éšåãããžãã¹ããžãã¯ãšã¬ã€ã¢ãŠãã®ãã©ãŒãããã«éäžã§ããããã«ãªããŸãã ãã¹ãŠã®ãããžã§ã¯ãã§åãã§ããäžè¬çãªå®åæãé衚瀺ã«ããã ãã§ãã«ã¹ã¿ã ãŠã£ãžã§ãããäœæããå¿ èŠã¯ãããŸããã
ç§ã®æé·ã®initStateã¡ãœããã¯5è¡ã®ã³ãŒãã§ããããŠã£ãžã§ããã¯é床ã®ãã¹ãã«æ©ãŸãããããšã¯ãªãã®ã§ãç§ãã¡ã¯ééããªãããŸããŸãªããŒãºãšãŠãŒã¹ã±ãŒã¹ãæã£ãŠããŸãã ãŸãã¯å¥ã®éçºã¹ã¿ã€ã«ã
ããŸãã«ãç§ã®ãã®ã ããããããã¯initStateïŒïŒ+ disposeïŒïŒ+ didUpdateDependanciesïŒïŒã§ãããæåŸã®2ã€ã®ãããããæ¬ èœããŠãããšãã°ãçºçããå¯èœæ§ããããŸãã
æ£èŠã®äŸã¯æ¬¡ã®ããã«ãªããšæããŸãã1ã€ã®ã¹ããªãŒã ã³ã³ãããŒã©ãŒãš2ã€ã®ã¢ãã¡ãŒã¿ãŒã³ã³ãããŒã©ãŒã䜿çšãããã¥ãŒãèšè¿°ããŸãã
ç§ãèŠãéãã3ã€ã®ãªãã·ã§ã³ããããŸãã
SingleStreamBuilderDoubleAnimationWidgetã§ãã4çªç®ã®ãªãã·ã§ã³ããããããããŸããããããã¯éçºè ã«ãšã£ãŠã¯åãªãäœæ¥ã§ãããäžè¬çã«ã¯ããªãé¢åã§ãã
ãŸãã3ã®èªç¥çè² è·ã¯ãæ°ããéçºè ã«ãšã£ãŠä»ã®2ã€ãããå€§å¹ ã«äœãããšã«ã泚æããŠãã ããã ã»ãšãã©ã®æ°ããéçºè ã¯ãTweenAnimationBuilderãååšããããšããç¥ããŸããããŸããSingleTickerProviderã®æŠå¿µãåŠã¶ããšã¯ãããèªäœãã¿ã¹ã¯ã§ãã ãã¢ãã¡ãŒã¿ãŒããã ããããšèšãã ãã§ãããç°¡åã§å ç¢ãªã¢ãããŒãã«ãªããŸãã
ä»æ¥ã¯äœããã³ãŒãã£ã³ã°ããŠã¿ãŸãã
2.ãã¥ãŒã³ãŒãã«å°éããåã«ã2ã€ã®TweenAnimationBuildersãšStreamBuilderãçŽ15ã®ã€ã³ãã³ãã¬ãã«ã§äœ¿çšããŸããããã§ããStreamã®å®åæã¯ãããããããŸãã
å³ã 15ã¬ãã«ã®ã€ã³ãã³ãã䜿çšããã³ãŒãã®å®éã®äŸã瀺ããŠãã ããã
ã©ã€ãã©ãªå ã®30è¡ã®ã³ãŒãã6è¡+æ°çŸè¡ã«çœ®ãæãããšãèªç¥çè² è·ãã©ã®ããã«è»œæžãããŸããïŒ ãããç§ã¯ã©ã€ãã©ãªãè¡ããéæ³ããç¡èŠããããšã¯ã§ããŸããããã®ã«ãŒã«ã¯ç¡èŠã§ããŸããã ããšãã°ãããã¯ããã±ãŒãžã¯ãããã¯ã¯ãã«ãã¡ãœããã§ã®ã¿äœ¿çšããå¿ èŠãããããšãäžç¢ºããªçšèªã§éç¥ããŸãã ããã§ãå¿é ããå¿ èŠã®ããè¿œå ã®å¶çŽããããŸãã
15kè¡ã®ã³ãŒããå«ããããžã§ã¯ãã«ã¯ããã©ãŒã«ã¹ããŒããããã¹ãã³ã³ãããŒã©ãŒãã·ã³ã°ã«ãã£ãã«ãŒãããã€ããŒããŸãã¯ã¹ããŒããã«ãŠã£ãžã§ããã®ããŸããŸãªã©ã€ããµã€ã¯ã«ã¡ãœãããå«ã200è¡æªæºã®ã³ãŒããå«ãŸããŠããå¯èœæ§ããããŸãã ããªãã¯ã©ã®ãããªèªç¥çéè² è·ã«ã€ããŠè©±ããŠããã®ã§ããïŒ
@Rudikszã¯ååçæ»æçã§ããããšããããŠãã ããã
ç§ãã¡ã¯æŠããã«å察ããããšãã§ããŸãã
ããã¯ã®å¶çŽã¯ç§ã®å¿é ã®äžã§æãå°ãªãã§ãã
ç¹ã«ããã¯ã«ã€ããŠè©±ããŠããã®ã§ã¯ãªããåé¡ã«ã€ããŠè©±ããŠããã
å¿
èŠã«å¿ããŠãå¥ã®è§£æ±ºçãèãåºãããšãã§ããŸãã
éèŠãªã®ã¯ç§ãã¡ã解決ãããåé¡ã§ãã
ããã«ããŠã£ãžã§ããã¯ãã«ãå ã§ç¡æ¡ä»¶ã«ã®ã¿äœ¿çšã§ããŸãïŒãŸãã¯ãããªãŒã®æ·±ããå€æŽããããšã¯ã§ããŸããïŒã
ããã¯ããã¯ã®å¶çŽãšåãã§ããã人ã ãããã«ã€ããŠäžæºãèšã£ãŠãããšã¯æããŸããã
ããã«ããŠã£ãžã§ããã¯ãã«ãå ã§ç¡æ¡ä»¶ã«ã®ã¿äœ¿çšã§ããŸãïŒãŸãã¯ãããªãŒã®æ·±ããå€æŽããããšã¯ã§ããŸããïŒã
ããã¯ããã¯ã®å¶çŽãšåãã§ããã人ã ãããã«ã€ããŠäžæºãèšã£ãŠãããšã¯æããŸããã
ããããåãã§ã¯ãããŸããã ããã«ç€ºãããŠããåé¡ã¯ããŠã£ãžã§ãããïŒåïŒæ§ç¯ãããåã«_prepares_ããã³ãŒãã«é¢é£ããŠããããã§ãã ç¶æ
ãäŸåé¢ä¿ãã¹ããªãŒã ãã³ã³ãããŒã©ãŒãªã©ãæºåããããªãŒæ§é ã®å€æŽãåŠçããŸãã åäžã®é¢æ°åŒã³åºãã®èåŸã«é ãããŠããå Žåã§ãããããã¯ããããbuildã¡ãœããã«å«ããã¹ãã§ã¯ãããŸããã
ãã®ããžãã¯ã®ãšã³ããªãã€ã³ãã¯ãbuildã¡ãœããã«å«ããããšã¯ã§ããŸããã
ãã«ãã¡ãœããã«ä»»æã®çš®é¡ã®åæåããžãã¯ã匷å¶çã«é 眮ããããšã¯ããã«ãã¡ãœããã§ãŠã£ãžã§ããããªãŒãäœæããããã«åŒ·å¶ããããšãšåãã§ã¯ãããŸããã buildã¡ãœããã®å šäœçãªçç±ã¯ãæ¢åã®ç¶æ ïŒå€æ°ã®ã»ããïŒãååŸãããŠã£ãžã§ããããªãŒãçæããŠãããã€ã³ãããããšã§ãã
éã«ãinitState / didUpdateWidgetã¡ãœããå ã«ãŠã£ãžã§ãããæ§ç¯ããã³ãŒããè¿œå ããããã«åŒ·å¶ããããšã«ãå察ããŸãã
çŸåšã®ããã«ãstatefulwidgetã©ã€ããµã€ã¯ã«ã¡ãœããã«ã¯éåžžã«æ確ãªåœ¹å²ãããããŸã£ããç°ãªãæžå¿µãæã€ã³ãŒããéåžžã«ç°¡åãã€ç°¡åã«åé¢ã§ããŸãã
æŠå¿µçã«ã¯ããã§èª¬æãããŠããåé¡ãç解ãå§ããŠããŸãããããã§ãå®éã®åé¡ãšã¯èŠãªãããŠããŸããã ãã¶ããããã€ãã®å®éã®äŸïŒã«ãŠã³ã¿ãŒã¢ããªã§ã¯ãªãïŒãç§ã®èããå€ããã®ã«åœ¹ç«ã€ãããããŸããã
ã¡ãªã¿ã«ãç§ã®ææ°ã®å®éšã§ãã
ããšãã°ã次ã®ããšã解決ããŸãã
Consumer(
provider: provider,
builder: (context, value) {
return Consumer(
provider: provider2,
builder: (context, value2) {
return Text('$value $value2');
},
);
},
)
æã£ãŠããããšã«ãã£ãŠïŒ
Consumer(
builder (context, watch) {
final value = watch(provider);
final value2 = watch(provider2);
},
)
watch
ãæ¡ä»¶ä»ãã§åŒã³åºãããšãã§ããå ŽåïŒ
Consumer(
builder: (context, watch) {
final value = watch(provider);
if (something) {
final value2 = watch(provider2);
}
},
)
ã«ã¹ã¿ã ã®StatelessWidget
/ StatefulWidget
åºæ¬ã¯ã©ã¹ã䜿çšããããšã§ã Consumer
å®å
šã«åãé€ãããšãã§ããŸãã
class Example extends ConsumerStatelessWidget {
<strong i="21">@override</strong>
Widget build(ConsumerBuildContext context) {
final value = context.watch(provider);
final value2 = context.watch(provider2);
}
}
äž»ãªåé¡ã¯ãããã¯1çš®é¡ã®ãªããžã§ã¯ãã«åºæã§ããããªããžã§ã¯ãã€ã³ã¹ã¿ã³ã¹ãåæ§ç¯å šäœã§äžè²«ããhashCodeãæã£ãŠãããšããäºå®ã«äŸåããŠæ©èœããããšã§ãã
ã§ããããããã¯ã®æè»æ§ã«ã¯ãŸã ã»ã©é ãã§ã
@rrousselGit StatelessWidget
/ StatefulWidget
ã¯ã©ã¹ãæ¡åŒµããŠãConsumerStatelessWidgetã®ãããªãã®ãäœæããªããŠãã BuildContext
æ¡åŒµã¡ãœããã䜿çšããŠã context.watch
ãããªãã®ãäœæã§ãããšæããŸããã¯ã©ã¹ãšãããã€ããŒã«ãAttachedWidgetsã䜿çšããŠç£èŠé¢æ°ãæäŸãããŸãã
ããã¯å¥ã®ãããã¯ã§ãã ããããtl; drããã®åé¡ã®è§£æ±ºçãšããŠAliExpressWidgetsã«äŸåããããšã¯ã§ããŸããïŒ https ïŒ
ãã®åé¡ã解決ããã«ã¯ã httpsïŒ//github.com/flutter/flutter/issues/12992ãšhttps://github.com/flutter/flutter/pull/33213ãåå ã§ã AliExpressWidgetsã䜿çšãããšãããã¯ãããŸãã
æŠå¿µçã«ã¯ããã§èª¬æãããŠããåé¡ãç解ãå§ããŠããŸãããããã§ãå®éã®åé¡ãšã¯èŠãªãããŠããŸããã
FlutterãSwiftUIãšæ¯èŒãããšãå®éã«åé¡ãããããšã¯æããã§ããããããç©äºã¯ããã»ã©å€§ããã¯ãããŸããã
Flutterãä»ã®äººããããåé¿ããããã«äžçæžåœåããã®ã§ãèŠã¥ãããããããŸããïŒAnimatedBuilderãStreamBuilderãConsumerãAnimatedOpacityãªã©ã®ç¹å®ã®ã±ãŒã¹ããšã«ã©ãããŒããããŸããStatefulWidgetã¯ãããã®å°ããªåå©çšå¯èœãªãŠãŒãã£ãªãã£ãå®è£ ããã®ã«æé©ã§ãããã¬ãã«ãäœãããŸãåå©çšã§ããªããã¡ã€ã³åºæã®ã³ã³ããŒãã³ãã®å Žåãããã¹ãã³ã³ãããŒã©ãŒãã¢ãã¡ãŒã·ã§ã³ããŸãã¯ããžãã¹ããžãã¯ãå¿ èŠãšãããã®ãå€æ°ããå¯èœæ§ããããŸãã éåžžã®è§£æ±ºçã¯ã匟䞞ãåãã§ãã®å®åæããã¹ãŠæžãããæ éã«æ§ç¯ããããããã€ããŒãšãªã¹ããŒã®ããªãŒãäœæããããšã§ãã ã©ã¡ãã®ã¢ãããŒããæºè¶³ã®ãããã®ã§ã¯ãããŸããã
@rrousselGitãèšãããã«ãæïŒUIKitïŒã§ã¯ã
ã¹ããŒããã«ã§ãããããåé¡ã¯éåžžã«äŒŒãŠããŸããèªååã§ããã®ã¯ãéå±ã§ãšã©ãŒãçºçããããäœæ¥ã§ãã
ãããŠãã¡ãªã¿ã«ãããã¯ã¯ããããŸã£ãã解決ããªããšæããŸãã ãã©ãã¿ãŒã®å éšãå€æŽããã«å¯èœãªå¯äžã®ã¢ãããŒãã¯ããã¯ã ãã§ãã
StatefulWidgetã¯ããããã®å°ããªåå©çšå¯èœãªãŠãŒãã£ãªãã£ãå®è£ ããã®ã«æé©ã§ãããåå©çšã§ããªããã¡ã€ã³åºæã®ã³ã³ããŒãã³ãã«ã¯äœã¬ãã«ã§ãããå€æ°ã®ããã¹ãã³ã³ãããŒã©ãã¢ãã¡ãŒã·ã§ã³ããŸãã¯ããžãã¹ããžãã¯ãå¿ èŠãšãããã®ããããŸãã
åå©çšã§ããªããã¡ã€ã³åºæã®ã³ã³ããŒãã³ããæ§ç¯ããã«ã¯ãé«ã¬ãã«ã®ãŠã£ãžã§ãããå¿ èŠã ãšèšããšãç§ã¯æ··ä¹±ããŸãã éåžžãããã¯æ£å察ã§ãã
AnimatedBuilderãStreamBuilderãConsumerãAnimatedOpacityã¯ãã¹ãŠãç¹å®ã®ãŠãŒã¹ã±ãŒã¹ãå®è£ ãããŠã£ãžã§ããã§ãã ãããã®é«ã¬ãã«ã®ãŠã£ãžã§ããã䜿çšã§ããªãã»ã©ç¹å®ã®ããžãã¯ãæã€ãŠã£ãžã§ãããå¿ èŠãªå Žåã¯ãäœã¬ãã«ã®APIã«ããããããŠã³ããŠãç¬èªã®ç¹å®ã®ãŠãŒã¹ã±ãŒã¹ãäœæã§ããããã«ããŸãã ãããããã€ã©ãŒãã¬ãŒãã¯ãç§ã®ç¬èªã®ãŠã£ãžã§ãããã¹ããªãŒã ããããã¯ãŒã¯ã³ãŒã«ãã³ã³ãããŒã©ãŒãªã©ã®ç¬èªã®çµã¿åããã管çããæ¹æ³ãå®è£ ããŠããŸãã
ããã¯ãããã¯ã®ãããªåäœããŸãã¯åã«ãèªååããæå±ããããšã¯ããããããã€ã©ãŒãã¬ãŒãã³ãŒããèšè¿°ããã«ã誰ãã欲ãããé«ã¬ãã«ã®åå©çšäžå¯èœãªããžãã¯ãåŠçã§ããäœã¬ãã«ã®ãŠã£ãžã§ãããå¿ èŠã ãšèšã£ãŠãããããªãã®ã§ãã
ã¹ããŒããã«ã§ãããããåé¡ã¯éåžžã«äŒŒãŠããŸããèªååã§ããã®ã¯ãéå±ã§ãšã©ãŒãçºçããããäœæ¥ã§ãã
ãŸãã __ "åå©çšäžå¯èœãªãã¡ã€ã³åºæã®ã³ã³ããŒãã³ããèªååããå¿ èŠããããŸãããã®å Žåãå€æ°ã®ããã¹ãã³ã³ãããŒã©ãã¢ãã¡ãŒã·ã§ã³ããŸãã¯ããžãã¹ããžãã¯ãå¿ èŠãšãããã®ã¯äœã§ã" __ïŒïŒ
@rrousselGitãèšãããã«ãæïŒUIKitïŒã§ã¯ã
ç§ã¯6ã7幎åïŒAndroidããããªã¢ã«ãã¶ã€ã³ã«åãæ¿ããé ïŒã«iOSãšAndroidã®éçºãè¡ããŸãããããã®ç®¡çãšãªãµã€ã¯ã«ã®ãã¥ãŒãåé¡ã«ãªã£ãŠããããšãèŠããŠããŸãããFlutterã¯è¯ããæªããèŠããŸããã çŸåšã®ç¶æ³ã«ã€ããŠè©±ãããšã¯ã§ããŸãããSwiftãšKotlinããªãªãŒã¹ããããšãã«èŸããŸããã
StatefulWidgetsã«æžã蟌ãããšãäœåãªããããŠããå®åæã¯ãã³ãŒãããŒã¹ã®çŽ1ïŒ ã§ãã ãšã©ãŒãçºçããããã§ããïŒ ã³ãŒãã®ãã¹ãŠã®è¡ããã°ã®æœåšçãªåå ã§ãããããå¿ ã確èªããŠãã ããã é¢åã§ããïŒ 15000ã®200è¡ã®ã³ãŒãããããŸããïŒ ç§ã¯æ¬åœã«ããã¯æããŸããããããã¯ç§ã®æèŠã§ãã Flutterã®ããã¹ã/ã¢ãã¡ãŒã·ã§ã³ã³ã³ãããŒã©ãŒã§ããfocusnodeã«ã¯ãã¹ãŠæ¹åå¯èœãªåé¡ããããŸãããåé·ã§ããããšã¯1ã€ã§ã¯ãããŸããã
人ã ãäœãéçºããŠããã®ããéåžžã«å€ãã®å®åæãå¿ èŠãªã®ããç§ã¯æ¬åœã«èå³ããããŸãã
ããã§ã³ã¡ã³ãã®ããã€ããèããšã1è¡ã§ã¯ãªã5è¡ã®ã³ãŒãã管çããã®ã5åé£ããããã«èãããŸãã ããã§ã¯ãããŸããã
ããšãã°ãåAnimationControllerã«å¯ŸããŠinitStateãèšå®ããŠç Žæ£ãã代ããã«ãäžåºŠå®è¡ããŠãã®ããžãã¯ãåå©çšããããããšã©ãŒãçºçããããããšã«åæããŸãããïŒ é¢æ°ã®äœ¿çšãšåãåçãåå©çšæ§ã ãã«ãé¢æ°ã«ããã¯ãé 眮ããã®ã¯åé¡ãããããšã«åæããŸãããééããªãããè¯ãæ¹æ³ããããŸãã
ããã§åé¡ãèªèããŠãã人ãšèªèããŠããªã人ã®éãã¯ãåè ã¯ReactãSwiftãKotlinãªã©ã®ä»¥åã«ããã¯ã®ãããªæ§é ã䜿çšããããšããããåŸè ã¯çŽç²ãªJavaã§ã®äœæ¥ãªã©ã䜿çšããŠããªãããšã§ãããŸãã¯Androidã ç§ã®çµéšã§ã¯ã確信ããå¯äžã®æ¹æ³ã¯ãããã¯ãè©ŠããŠãæšæºçãªæ¹æ³ã«æ»ãããšãã§ãããã©ããã確èªããããšã ãšæããŸãã å€ãã®å Žåãç§ã®çµéšã§ã¯ãå€ãã®äººãåã³ããããããšãã§ããŸããã ããªããããã䜿ããšããããªãã¯ãããç¥ã£ãŠããŸãã
ãã®ããã«ãå°ããªãããžã§ã¯ãã«flutter_hooksã䜿çšããŠããããã©ã®ããã«æ©èœãããã確èªããŠãããããã©ã«ãã®æ¹æ³ã§ããçŽãããšããå§ãããŸãã @Hixieã®ææ¡ã®ããã«ãã¢ããªã®ããŒãžã§ã³ãäœæããŠèªãã ãã§ã¯
@Hixieã®ææ¡ã®ããã«ãã¢ããªã®ããŒãžã§ã³ãäœæããŠèªãã ãã§ã¯
ç§ã¯ãããã€ããŒãè©Šãã®ã«äœæ¥ãç¡é§ã«ãããããã¯ãè©Šãã®ã«ããã«å€ãã®æ¥ãè²»ãããŸããããã©ã¡ããè¯ã解決çã§ãããšã¯æããŸããã§ããã ãããããªãã®ããã«åããªããçŽ æŽãããã
ç§ãããªããæã£ãŠããããšãåé¡ã«ããªãã®ææ¡ããããœãªã¥ãŒã·ã§ã³ãããããšããããã«ã¯ãããªãã¯ãã®å©ç¹ãå®èšŒããå¿ èŠããããŸãã ãã©ãã¿ãŒããã¯ã䜿çšããäŸãšãã®å®è£ ã確èªããŸããã ãããã
ãã¬ãŒã ã¯ãŒã¯ã«è¿œå ãããå®åçãªåæžã³ãŒããäœã§ãããã¹ããŒããã«/ã¹ããŒãã¬ã¹ãŠã£ãžã§ããã¯å€æŽãããªããŸãŸã«ããŠããããšãæã¿ãŸãã ãã®äŒè©±ã«è¿œå ã§ãããã®ã¯ãã以äžãããŸããã
ããã¯ã«ã€ããŠè©±ããã«ããŒããå€æŽã§ããæ¶ç©ºã®äžçã§ãããäžåºŠå§ããŸãããã
è°è«ãããŠããåé¡ã¯æ¬¡ã®ãšããã§ãã
Widget build(context) {
return ValueListenableBuilder<String>(
valueListenable: someValueListenable,
builder: (context, value, _) {
return StreamBuilder<int>(
stream: someStream,
builder: (context, value2) {
return TweenAnimationBuilder<double>(
tween: Tween(...),
builder: (context, value3) {
return Text('$value $value2 $value3');
},
);
},
);
},
);
}
ãã®ã³ãŒãã¯èªã¿åãå¯èœã§ã¯ãããŸããã
æ§æã次ã®ããã«å€æŽããæ°ããããŒã¯ãŒããå°å ¥ããããšã§ãèªã¿ãããã®åé¡ãä¿®æ£ã§ããŸãã
Widget build(context) {
final value = keyword ValueListenableBuilder(valueListenable: someValueListenable);
final value2 = keyword StreamBuilder(stream: someStream);
final value3 = keyword TweenAnimationBuilder(tween: Tween(...));
return Text('$value $value2 $value3');
}
ãã®ã³ãŒãã¯éåžžã«èªã¿ããããããã¯ãšã¯ç¡é¢ä¿ã§ãããå¶éã®åœ±é¿ãåããŸããã
èªã¿ãããã®åäžã¯ãè¡æ°ã§ã¯ãªãããã©ãŒããããšã€ã³ãã³ãã§ãã
äŸïŒ
Widget build(context) {
return Scaffold(
body: StreamBuilder(
stream: stream,
builder: (context, value) {
return Consumer<Value2>(
builder: (context, value2, child) {
return Text('${value.data} $value2');
},
);
},
),
);
}
ç§ãã¡ã¯æã€ããšãã§ããŸãïŒ
Widget build(context) {
return Scaffold(
body: {
final value = keyword StreamBuilder(stream: stream);
final value2 = keyword Consumer<Value2>();
return Text('${value.data} $value2');
}
);
}
ãããé¢é£ããŠããçç±ã¯ããã«ããŒã¯æè¡çã«ã¯ç¶æ ããžãã¯ãåå©çšããæ¹æ³ã ããã§ãã ãããã圌ãã®åé¡ã¯ããã®ã³ã¡ã³ãhttps://github.com/flutter/flutter/issues/51752#issuecomment -669626522ã®ããã«ã_many_ãã«ããŒã䜿çšããäºå®ã®å Žåãã³ãŒããèªã¿ã«ãããªãããšã§ãã
ãã®æ°ããæ§æã§ãèªã¿ãããã®åé¡ãä¿®æ£ããŸããã ãã®ããããã«ããŒã«ããã«å€ãã®ãã®ãæœåºã§ããŸãã
ãããã£ãŠãããšãã°ããã®ã³ã¡ã³ãã§èšåãããŠããuseFilter
ããã«ãªããŸãã
FilterBuilder(
debounceDuration: const Duration(seconds: 2),
builder: (context, filter) {
return TextField(onChange: (value) => filter.value = value);
}
)
ãã®åŸãæ°ããããŒã¯ãŒãã§äœ¿çšã§ããŸãã
class ChatScreen extends HookWidget {
const ChatScreen({Key key}) : super(key: key);
<strong i="15">@override</strong>
Widget build(BuildContext context) {
final filter = keyword FilterBuilder(debounceDuration: const Duration(seconds: 2));
final userId = keyword Consumer(authProvider).userId;
final chatId = keyword Consumer(selectedChatProvider);
final chat = keyword QueryBuilder(ChatQuery(userId: userId, chatId: chatId, filter: filter.value));
return Column(
children: [
Searchbar(onChanged: (value) => filter.value = value),
Expanded(
child: ChatList(chat: chat),
),
],
);
}
}
é¢æ°å ã®ãã«ããŒã®çµã¿åãããæœåºããããšã§ããã®ãããªããŒã¯ãŒãã§ãåãããšãã§ããŸãã
Builder<Chat> ChatBuilder() {
final filter = keyword FilterBuilder(debounceDuration: const Duration(seconds: 2));
final userId = keyword Consumer(authProvider).userId;
final chatId = keyword Consumer(selectedChatProvider);
final chat = keyword QueryBuilder(ChatQuery(userId: userId, chatId: chatId, filter: filter.value));
return Builder(chat);
}
class ChatScreen extends HookWidget {
const ChatScreen({Key key}) : super(key: key);
<strong i="21">@override</strong>
Widget build(BuildContext context) {
final chat = keyword ChatBuilder();
return Column(
children: [
Searchbar(onChanged: (value) => filter.value = value),
Expanded(
child: ChatList(chat: chat),
),
],
);
}
}
æããã«ããã®ãããªæ§æã®ãã¹ãŠã®æå³ã«ã€ããŠã¯ããŸãèããããŠããŸããã§ããã ãããããããåºæ¬çãªèãæ¹ã§ãã
ããã¯ã¯ãã®æ©èœã§ãã
ããã¯ã«ã¯ãèšèªæ©èœã§ã¯ãªãããã±ãŒãžãšããŠå®è£
ããããããå¶éããããŸãã
ãããŠãããŒã¯ãŒãã¯use
ã keyword StreamBuilder
ã¯use StreamBuilder
ãæçµçã«ã¯useStream
ãšããŠå®è£
ãããŸãã
ãã®ã³ãŒãã¯éåžžã«èªã¿ããããªã£ãŠããŸã
ããã¯æèŠã®åé¡ã ãšæããŸãã ç§ã¯ãããªããããèªã¿ããããšèª¬æããããŒãžã§ã³ã®æ¹ãåªããŠãããšèãã人ãããããšã«åæããŸãã å人çã«ã¯ããã£ãšæ確ãªéæ³ã®ãªãããŒãžã§ã³ã奜ãã§ãã ããããç§ã¯2çªç®ã®ã¹ã¿ã€ã«ãå¯èœã«ããããšã«ç°è«ã¯ãããŸããã
ããã¯èšã£ãŠãã次ã®ã¹ãããã¯@TimWhitingã®ã¢ããªïŒhttps://github.com/TimWhiting/local_widget_state_approaches/blob/master/lib/stateful/counter.dartïŒã§äœæ¥ããŠããã¹ãŠã®åé¡ããããã®ã«ããããšã§ãã解決ãããããšã
https://github.com/flutter/flutter/issues/51752#issuecomment -670959424ã¯ãHooks inReactã®ã€ã³ã¹ãã¬ãŒã·ã§ã³ãšã»ãŒåãã§ãã Builderãã¿ãŒã³ã¯ãReactã§äžè¬çã ã£ãRender Propsãã¿ãŒã³ãšåãããã«èŠããŸãïŒãã ããåæ§ã«æ·±ãããªãŒã«ãªããŸããïŒã ãã®åŸã @ trueadmã¯ã¬ã³ããªã³ã°ããããã®ã·ã³ã¿ãã¯ã¹ã·ã¥ã¬ãŒãææ¡ãããã®åŸãããã¯ã«ã€ãªãããŸããïŒäžèŠãªã©ã³ã¿ã€ã ãªãŒããŒããããåé€ããããïŒã
`Widget build(context) {
return ValueListenableBuilder<String>(
valueListenable: someValueListenable,
builder: (context, value, _) {
return StreamBuilder<int>(
stream: someStream,
builder: (context, value2) {
return TweenAnimationBuilder<double>(
tween: Tween(...),
builder: (context, value3) {
return Text('$value $value2 $value3');
},
);
},
);
},
);
}`
èªã¿ããããšã€ã³ãã³ããåé¡ã§ããå Žåãããã¯æ¬¡ã®ããã«æžãçŽãããšãã§ããŸãã
<strong i="8">@override</strong>
Widget build(context) {
return ValueListenableBuilder<String>(
valueListenable: someValueListenable,
builder: (context, value, _) => buildStreamBuilder(value),
);
}
StreamBuilder<int> buildStreamBuilder(String value) => StreamBuilder<int>(
stream: someStream,
builder: (context, value2) => buildTweenAnimationBuilder(value, value2),
);
Widget buildTweenAnimationBuilder(String value, AsyncSnapshot<int> value2) =>
TweenAnimationBuilder<double>(
duration: Duration(milliseconds: 500),
tween: Tween(),
builder: (context, value3, _) => Text('$value $value2 $value3'),
);
é¢æ°ãããªãã®ãã®ã§ã¯ãªãå ŽåããŸãã¯åå©çšæ§ãå¿ èŠãªå Žåã¯ããŠã£ãžã§ãããšããŠããããæœåºããŸã
class NewWidget extends StatelessWidget {
var someValueListenable;
var someStream;
<strong i="12">@override</strong>
Widget build(context) {
return ValueListenableBuilder<String>(
valueListenable: someValueListenable,
builder: (context, value, _) {
return MyStreamedWidget(value, someStream);
},
);
}
}
class MyStreamedWidget extends StatelessWidget {
const MyStreamedWidget(
this.value,
this.someStream, {
Key key,
}) : super(key: key);
final String value;
final Stream someStream;
<strong i="13">@override</strong>
Widget build(BuildContext context) {
return StreamBuilder<int>(
stream: someStream,
builder: (context, value2) => MyAnimatedWidget(value, value2),
);
}
}
class MyAnimatedWidget extends StatelessWidget {
final String value;
final AsyncSnapshot<int> value2;
const MyAnimatedWidget(
this.value,
this.value2, {
Key key,
}) : super(key: key);
<strong i="14">@override</strong>
Widget build(BuildContext context) {
return TweenAnimationBuilder<double>(
tween: Tween(),
builder: (context, value3, _) {
return Text('$value $value2 $value3');
},
);
}
}
ããªãã®äŸã«ã¯ãæ°ããããŒã¯ãŒããæ©èœãä¿èšŒãããã®ã¯äœããããŸããã
ç§ã¯ããªããäœãèšãããšããŠããã®ãç¥ã£ãŠããŸãã 'value'å€æ°ã¯ããã¹ãŠã®ãŠã£ãžã§ãã/é¢æ°åŒã³åºããééããå¿ èŠããããŸãããããã¯ãã¢ããªã±ãŒã·ã§ã³ã®èšèšæ¹æ³ã®çµæã«ãããŸããã ãŠãŒã¹ã±ãŒã¹ã«å¿ããŠãããã«ããã¡ãœãããšã«ã¹ã¿ã ãŠã£ãžã§ããã®äž¡æ¹ã䜿çšããŠã³ãŒããåå²ããåãå€æ°ã3ã€ã®åŒã³åºãã®ãã§ãŒã³ã«æž¡ãå¿ èŠã¯ãããŸããã
åå©çšå¯èœãªã³ãŒãã¯ãå€éšã®å¯äœçšïŒDependentWidgetsãïŒåïŒã°ããŒãã«ç¶æ ãªã©ïŒã«ã§ããã ãäŸåããªãå Žåã«åå©çšã§ããŸãã
@Rudikszããã§ã®è°è«ã«äœãè¿œå ããŠããªããšæããŸãã ç§ãã¡ã¯äžæ¥äžããããè¡ã£ãŠããã®ã§ããããã®åé¡ã軜æžããããã®æŠç¥ãèªèããŠããŸãã åé¡ããªããšæãããå Žåã¯ããã®ãŸãŸäœ¿çšãç¶ããããšãã§ããŸããããŸã£ãã圱é¿ã¯ãããŸããã
æããã«ããããæ ¹æ¬çãªåé¡ç¹ãšèŠãªããŠãã人ã¯ããããããŸããååŸã«ãµã€ã¯ãªã³ã°ããã ãã§ã¯æå³ããããŸããã ããªãã¯ãããŸããŸãªè°è«ãéããŠã圌ããæããã®ãæãŸãªãããšã人ã ã«çŽåŸãããããããã§èª°ãã®å¿ãå€ãããããã€ããã¯ãããŸããã ãã®è°è«ã®èª°ããæããã«åœŒãã®ãã«ãã®äžã§Flutterã«æ°çŸãŸãã¯æ°åæéãæã£ãŠããŸãããããŠç§ãã¡å šå¡ãç©äºã«åæããã¹ãã§ãããšã¯æåŸ ãããŠããŸããã
ããã¯æèŠã®åé¡ã ãšæããŸãã ç§ã¯ãããªããããèªã¿ããããšèª¬æããããŒãžã§ã³ã®æ¹ãåªããŠãããšèãã人ãããããšã«åæããŸãã å人çã«ã¯ããã£ãšæ確ãªéæ³ã®ãªãããŒãžã§ã³ã奜ãã§ãã ããããç§ã¯2çªç®ã®ã¹ã¿ã€ã«ãå¯èœã«ããããšã«ç°è«ã¯ãããŸããã
ãããæèŠã®åé¡ã§ãããªãã°ãç§ã¯ãããäžæ¹åã«ããªãåã£ãŠãããšæããŸãã
value1
ãšvalue2
ïŒããããã«ãããããã1ã€ã¯ããã«ãã®äžéšã®åé¢ãšäžå€®ã«é
眮ããŸãã ããã¯æ確ãªæ§æ解æ/ã¡ã³ããã³ã¹ã®åå©ã§ããäžè¬çãªæå³ã§ãããã¯ãããã奜ã¿ã®åé¡ã§ããããšãããããŸããã ããããFlutterã«ã¯ãäžè¬çã«ãåç·æ°ãã€ã³ãã³ããŒã·ã§ã³ãããã³ä¿¡å·ïŒãã€ãºæ¯ã«ç¹ã«åé¡ããããŸãã ç§ã¯Dartã³ãŒãã§å®£èšçã«ããªãŒã圢æããæ©èœã絶察ã«_倧奜ã_ã§ãããç¹ã«ã©ããããããã«ããŒã®è€æ°ã®ã¬ã€ã€ãŒã«äŸåããŠããå Žåã¯ãéåžžã«èªããªã/åé·ãªã³ãŒãã«ã€ãªããå¯èœæ§ããããŸãã ãããã£ãŠããã®æŠããç¶ç¶çã«æŠã£ãŠããFlutterèªäœã®ã³ã³ããã¹ãã§ã¯ããã®çš®ã®æé©åã¯ããã®äžè¬çãªåé·æ§ã®ããè延ããŠããåé¡ãšæŠãããã®éåžžã«åªããããŒã«ãæäŸããããããã©ãŒæ©èœã§ãã
TL; DR-Flutterã«åºæã®è¡æ°ãšã€ã³ãã³ããäžè¬çã«å€ããããFlutterã®ã€ã³ãã³ããšè¡æ°ãå€§å¹ ã«åæžãããã®ã¯ãã¹ãŠäºéã«äŸ¡å€ããããŸãã
@Rudikszããã§ã®è°è«ã«äœãè¿œå ããŠããªããšæããŸãã ç§ãã¡ã¯äžæ¥äžããããè¡ã£ãŠããã®ã§ããããã®åé¡ã軜æžããããã®æŠç¥ãèªèããŠããŸãã åé¡ããªããšæãããå Žåã¯ããã®ãŸãŸäœ¿çšãç¶ããããšãã§ããŸããããŸã£ãã圱é¿ã¯ãããŸããã
ãããã³ã¢ãã¬ãŒã ã¯ãŒã¯ã®å€æŽã§ããå Žåãé€ããŠãããã¯ç§ã«åœ±é¿ãäžããŸããïŒ
æããã«ããããæ ¹æ¬çãªåé¡ç¹ãšèŠãªããŠãã人ã¯ããããããŸããååŸã«ãµã€ã¯ãªã³ã°ããã ãã§ã¯æå³ããããŸããã ããªãã¯ãããŸããŸãªè°è«ãéããŠã圌ããæããã®ãæãŸãªãããšã人ã ã«çŽåŸãããããããã§èª°ãã®å¿ãå€ãããããã€ããã¯ãããŸããã ãã®è°è«ã®èª°ããæããã«åœŒãã®ãã«ãã®äžã§Flutterã«æ°çŸãŸãã¯æ°åæéãæã£ãŠããŸãããããŠç§ãã¡å šå¡ãç©äºã«åæããã¹ãã§ãããšã¯æåŸ ãããŠããŸããã
ããã§ãããã®éŠ¬ã¯ãã§ã«äœåºŠã殎ãããŠæ»ãã§ããŸã£ãã®ã§ããã以äžã³ã¡ã³ãã«çããçœ ã«ã¯ãŸããŸããã
ãã«ããŒã¯ãæè¡çã«ã¯ç¶æ ããžãã¯ãåå©çšããæ¹æ³ã§ãã ãããã圌ãã®åé¡ã¯ãã³ãŒããããŸãèªã¿ã«ãããªãããšã§ãã
ããã¯ãããå®å šã«è¿°ã¹ãŠããŸãã Flutterã®çšèªã§èãããšãåäžè¡ã®ãã«ããŒãå¿ èŠã§ãã
æ°åã®ã¿ããšè¡ãå¿ èŠãšããªããããŠã£ãžã§ããã®ã©ã€ããµã€ã¯ã«ã«ã«ã¹ã¿ã ãã€ã©ãŒãã¬ãŒããããã¯ã§ãããã«ããŒã
ããã¹ãŠããŠã£ãžã§ããã§ããããšãããã³ãã©ã¯ãããã§ã¯ç¹ã«è¯ãããšã§ã¯ãããŸããã ãã«ããŒã®é¢é£ã³ãŒãã¯éåžžãã»ããã¢ããã®å°éå ·ãšããã«ãfxnãå¿ èŠãšããã¹ããŒããã«ãªãã®ã§ãã ãã¹ãŠã®æ¹è¡ãšã¿ãã¯åºæ¬çã«ç¡æå³ã§ãã
ãããã³ã¢ãã¬ãŒã ã¯ãŒã¯ã®å€æŽã§ããå Žåãé€ããŠãããã¯ç§ã«åœ±é¿ãäžããŸããïŒ
@Rudikszã¹ããŒããã«ãŠã£ãžã§ãããå€æŽããããšãææ¡ããŠãã人ã¯ããªããšæããŸãã å¿
èŠã«å¿ããŠããã€ã§ãçŸåšã®åœ¢åŒã§äœ¿çšã§ããŸãã ç§ãã¡ãæãã€ã解決çãäœã§ãããå€æŽââã®ãªãã¹ããŒããã«ãŠã£ãžã§ããã䜿çšããããå¥ã®ã¿ã€ãã®ãŠã£ãžã§ãããå®å
šã«äœ¿çšããŸãã ã¹ããŒããã«ãŠã£ãžã§ãããæªããšèšã£ãŠããã®ã§ã¯ãªããããæ§æå¯èœãªãŠã£ãžã§ããç¶æ
ãå¯èœã«ããå¥ã®ã¿ã€ãã®ãŠã£ãžã§ãããå¿
èŠãªã ãã§ãã ããã¯ãé¢é£ä»ãããã1ã€ã®ç¶æ
ãªããžã§ã¯ãã®ä»£ããã«è€æ°ã®ç¶æ
ãªããžã§ã¯ããšãå¥åã§ããããããã®ç¶æ
ãªããžã§ã¯ãã«ã¢ã¯ã»ã¹ã§ãã1ã€ã®ãã«ãé¢æ°ãå«ãã¹ããŒããã«ãŠã£ãžã§ãããšèããŠãã ããã ãã®ããã«ããŠãå
±éã®ç¶æ
ã®ããããïŒãã®ç¶æ
ã«é¢é£ä»ããããç¶æ
ããžãã¯ãšãšãã«ïŒåå©çšã§ãããããã®initState
ãšdispose
ãã§ã«å®è£
ãããŠããŸãã æ¬è³ªçã«ããã¢ãžã¥ãŒã«åãããç¶æ
ã§ãããããŸããŸãªç¶æ³ã§ããŸããŸãªæ¹æ³ã§æ§æã§ããŸãã ç¹°ãè¿ããŸãããããã¯å
·äœçãªææ¡ã§ã¯ãããŸããããããããå¥ã®èãæ¹ã§ãã ãã¶ãããã¯ãã£ãšflutter
ãããªè§£æ±ºçã«ãªããããããŸããããç§ã«ã¯ããããŸããã
ããã¯èšã£ãŠãã次ã®ã¹ãããã¯@TimWhitingã®ã¢ããªïŒhttps://github.com/TimWhiting/local_widget_state_approaches/blob/master/lib/stateful/counter.dartïŒã§äœæ¥ããŠããã¹ãŠã®åé¡ããããã®ã«ããããšã§ãã解決ãããããšã
ãã®åé¡ã¯æ¬è³ªçã«åã«ããã«ããæ»ã®1ã€ã§ãããããããã¯æ³šæãå¿ èŠã§ãã ããã¯åã«è¥å€§åãè¿œå ããã³ãŒãããŒã¹å šäœã®å¯èªæ§ãäœäžãããŸãã ãã®åœ±é¿ã¯ãã¯ã©ã¹å šäœã100è¡æªæºã§ããã®ååãã¢ãã¡ãŒã¿ãŒã³ã³ãããŒã©ãŒã®ç®¡çã«è²»ããããŠããå°ããªãŠã£ãžã§ããã§æãã²ã©ãæããããŸãã ãããã£ãŠããããã®äŸã®ãã¡30ãèŠããšäœã衚瀺ããããããããŸãããã1ã€ã¯è¡šç€ºãããŸããã
ããã¯æ¬åœã«ããã®éãã§ãïŒ
<strong i="10">@override</strong>
Widget build(BuildContext context) {
final controller = get AnimationController(vsync: this, duration: widget.duration);
//do stuff
}
ãã®ïŒ
AnimationController _controller;
<strong i="14">@override</strong>
void initState() {
super.initState();
_controller = AnimationController(vsync: this, duration: widget.duration);
}
<strong i="15">@override</strong>
void didUpdateWidget(Example oldWidget) {
super.didUpdateWidget(oldWidget);
if (widget.duration != oldWidget.duration) {
_controller.duration = widget.duration;
}
}
<strong i="16">@override</strong>
void dispose() {
_controller.dispose();
super.dispose();
}
<strong i="17">@override</strong>
Widget build(BuildContext context) {
//Do Stuff
}
ãã以äžã«èª¬æããã®ã«è¯ãæ¹æ³ã¯ãããŸããã ãã®ãŠãŒã¹ã±ãŒã¹ã¯ãä»»æã®ã³ã³ãããŒã©ãŒã¿ã€ãã®ãªããžã§ã¯ãã«æ¡åŒµã§ããŸãã AnimatorControllerãFocusControllerãããã³TextEditingControllerã¯ããããããæ¥åžžã®äœ¿çšã§ç®¡çããã®ã«æãäžè¬çã§ç ©ããããã®ã§ãã ä»ãã¡ããã©åç50ããŸãã¯ãããã®100ãç§ã®ã³ãŒãããŒã¹å šäœã«æ£ãã°ã£ãŠããŸãã
ãã¡ããããããã«ã¹ã¿ã ã³ã³ãããŒã©ãŒã«æ¡åŒµããããšãã§ããŸãã ã³ã³ãããŒã©ãŒã䜿çšãããšããæŠå¿µå šäœã¯ãFlutterã§ã¯ããŸãé åçã§ã¯ãããŸãããããã¯ãã³ã³ãããŒã©ãŒããã®ããã«ããŒãã¹ãã©ããã管çãããã³ç Žæ£ããå¿ èŠãããããã§ããããã¯ãç ©ãããããã°ãçºçãããããã®ã§ãã ããã«ãããç¬èªã®äœæãé¿ãã代ããã«ã«ã¹ã¿ã ã®StatefulWidgets / Builderãäœæããããšãã§ããŸãã ãã«ããŒã«ã¯èªã¿ãããã®åé¡ãããããïŒãŸãã¯ãå°ãªããšããåé·ã§ç©ºçœãå€ãããïŒãã³ã³ãããŒã©ãŒã¿ã€ãã®ãªããžã§ã¯ãã䜿ãããããå ç¢ã§ãããšäŸ¿å©ã§ãã
ããã¯ããªãããŒã§ã
ã¯ããAPIã®èšèšã«ã¯æ³šæãå¿ èŠã§ãã ç§ã®ç掻ãžããããã
ãããã£ãŠããããã®äŸã®ãã¡30ãèŠããšäœã衚瀺ããããããããŸãããã1ã€ã¯è¡šç€ºãããŸããã
圹ç«ã€ã®ã¯30ã®äŸã§ã¯ãªããã確ãã«ããã®äŸã§ã¯æ©èœããŸãããå®éã®äŸã§ã¯ãããŸããããšèšããããªæ¹æ³ã§åçŽåã§ããªãã»ã©ç²Ÿå·§ãª1ã€ã®äŸã§ãã
圹ç«ã€ã®ã¯30ã®äŸã§ã¯ãªããã確ãã«ããã®äŸã§ã¯æ©èœããŸãããå®éã®äŸã§ã¯ãããŸããããšèšããããªæ¹æ³ã§åçŽåã§ããªãã»ã©ç²Ÿå·§ãª1ã€ã®äŸã§ãã
ãã§ã«äœåºŠãèšããŸãããããã®ãããªããã¯ã®å€æã¯äžå
¬å¹³ã§ãã
ããã¯ã¯ã以åã¯äžå¯èœã ã£ãäœããå¯èœã«ããããšã§ã¯ãããŸããã ãã®çš®ã®åé¡ã解決ããããã®äžè²«ããAPIãæäŸããããšã§ãã
åçŽåã§ããªããã®ã衚瀺ããã¢ããªã±ãŒã·ã§ã³ãèŠæ±ããããšã¯ãæšã«ç»ãèœåã«ãã£ãŠéãå€æããããšã§ãã
ç§ãã¡ã¯ããã¯ãå€æããããšããŠããã ãã§ãªããããŸããŸãªãœãªã¥ãŒã·ã§ã³ãè©äŸ¡ããŠããã¹ãŠã®äººã®ããŒãºã«å¯Ÿå¿ãããœãªã¥ãŒã·ã§ã³ããããã©ããã確èªããããšããŠããŸãã
ïŒå®éã«åææ¡ã«ã¢ããªã±ãŒã·ã§ã³ãäœæããŠæ¯èŒããã®ã§ã¯ãªããããã§ããŸããŸãªææ¡ãã©ã®ããã«è©äŸ¡ããã®ãèå³ããããŸãã代ããã«ã©ã®è©äŸ¡ææšãææ¡ããŸããïŒïŒ
ãã®åé¡ã®è§£æ±ºçãå€æããé©åãªæ¹æ³ã¯ãã¢ããªã±ãŒã·ã§ã³ã§ã¯ãããŸããïŒAPIã®åã ã®äœ¿çšæ³ã¯ãããã§ã®äŸã®ããã«åŽäžãããããïŒã
ææ¡ããã解決çãå€æããå¿ èŠãããã®ã¯æ¬¡ã®ãšããã§ãã
ãã®ã°ãªããã§è©äŸ¡ãããšã Property
/ addDispose
ææ¡ã¯ããçµæã®ã³ãŒãã®æ¹ãåªããŠãããããšããç¹ã§åªããŠããå¯èœæ§ããããŸãã ã¹ã³ã¢ã¯ä»ããããŸãããåå©çšæ§ãšæè»æ§ã®äž¡æ¹ã«å¯ŸããŠè©äŸ¡ãäžååã§ãã
ããããã®ææ¡ãå®éã«å®éã«èŠãã«ããããã®è³ªåã«çããæ¹æ³ãããããŸããã
ã©ãããŠïŒ
Property
ã䜿çšããŠã¢ããªã±ãŒã·ã§ã³ãäœæããå¿
èŠã¯ãããŸãã
æ¢åã®* Builderã䜿çšããŠãææ¡ããããœãªã¥ãŒã·ã§ã³ã䜿çšããŠããããåå®è£
ããããšãã§ããŸãã
ãã®ã¹ã¬ããã«ãªã¹ããããŠããããã¯ããŸãã¯Reactã³ãã¥ããã£ã§äœæãããããã€ãã®ããã¯ãåå®è£
ããããšãã§ããŸãïŒãªã³ã©ã€ã³ã§å©çšã§ããããã¯ã®ã³ã³ãã€ã«ã¯å€æ°ãããŸãïŒã
Property
ã䜿çšããŠã¢ããªã±ãŒã·ã§ã³ãäœæããå¿ èŠã¯ãããŸãã
æ®å¿µãªãããããã§ã¯ããªãã®æ¬èœãå ±æããŸããïŒããããã£ïŒhttps://github.com/flutter/flutter/issues/51752#issuecomment-667737471ïŒãå€ãåŠçããå¿ èŠããããšèšããŸã§ãããŸãæ©èœãããšæã£ããšããäºå®ã«ãã£ãŠç€ºãããŠããŸãïŒãŠã£ãžã§ãããšåãAPIã䜿çšããããŒã«ã«ç¶æ ã®äž¡æ¹ããããããèµ·åãããŸã§å¶çŽã§ããããšã«æ°ã¥ããŠããŸããã§ããïŒã ãã®åé¡ã解決ããããŒãžã§ã³ã®PropertyãæäŸããå Žåãããã¯ééããªãåé¡ãªãã®ã§ããããããããšãã«ããŒãããŠããªãæ°ããåé¡ãããã®ã§ããããã ç®æšããªããã°ãç§ãã¡å šå¡ãç®æšã§ããããšã«åæããŸããç§ãã¡ãäœã®ããã«ãœãªã¥ãŒã·ã§ã³ãèšèšããŠããã®ãããããŸããã
æ¢åã®* Builderã䜿çšããŠãææ¡ããããœãªã¥ãŒã·ã§ã³ã䜿çšããŠããããåå®è£ ããããšãã§ããŸãã
æããã«_any_ã§ã¯ãããŸããã ããšãã°ãOPã§1ã€æäŸããŸããããæåã®ããããã£ã®ææ¡ïŒhttps://github.com/flutter/flutter/issues/51752#issuecomment-664787791ïŒãè¡ã£ããšãã«ãå ã®ãã«ããŒã
ãã®ã¹ã¬ããã«ãªã¹ããããŠããããã¯ããŸãã¯Reactã³ãã¥ããã£ã§äœæãããããã€ãã®ããã¯ãåå®è£ ããããšãã§ããŸãïŒãªã³ã©ã€ã³ã§å©çšã§ããããã¯ã®ã³ã³ãã€ã«ã¯å€æ°ãããŸãïŒã
ã©ãããå§ããŠãããŸããŸããã åé¡ã説æããŠãããšæãããç¹ã«è¯ãäŸããããããã¯ã䜿çšããŠããå Žåã¯ãããã@TimWhitingã®ãªããžããªã«è¿œå ããŸãããã éèŠãªã®ã¯ãåãããšãè€æ°ã®ç°ãªãæ¹æ³ã§å®è£ ããããšã§ããã¢ã€ãã¢ãã©ãããæ¥ãã®ãã¯æ°ã«ããŸããã
圹ç«ã€ã®ã¯30ã®äŸã§ã¯ãªããã確ãã«ããã®äŸã§ã¯æ©èœããŸãããå®éã®äŸã§ã¯ãããŸããããšèšããããªæ¹æ³ã§åçŽåã§ããªãã»ã©ç²Ÿå·§ãª1ã€ã®äŸã§ãã
èªããªããã«ããŒããã°ãçºçããããã©ã€ããµã€ã¯ã«ã®å®åæãªãã§ãAnimatorControllerïŒãŸãã¯èããããä»ã®åå©çšå¯èœãªã¹ããŒããã«ã³ã³ããŒãã³ãïŒã䜿çšããããšããåçŽãªé¡æã»ã©æã®èŸŒãã ãã®ã¯ãããŸããã
èŠæ±ãããèªã¿ããããšå ç¢æ§ã®å©ç¹ã«ãæ±çšçãªæ¹æ³ã§å¯ŸåŠãããœãªã¥ãŒã·ã§ã³ã¯ææ¡ãããŠããŸããã
ãã®åé¡ã¯ããã«ããŒã«ã¯ã·ã³ã¿ãã¯ã¹ã·ã¥ã¬ãŒãå¿ èŠãã«ååãå€æŽãããåãè°è«ã«ã€ãªããå¯èœæ§ããããããç§ã¯_any_ãã«ããŒãè¡ããšããäºå®ã䞻匵ããŸãã
è¡ãããä»ã®ãã¹ãŠã®åŒæ°ïŒ AnimationController
äœæãç Žæ£ãªã©ïŒã¯ããããããã«ããŒã«æœåºã§ããããšã«åºã¥ããŠè¡ãããŸãã
Widget build(context) {
return AnimationControllerBuilder(
duration: Duration(seconds: 2),
builder: (context, animationController) {
}
);
}
çµå±ã®ãšãããå®ç§ãªäŸã¯ãStreamBuilderå šäœãåå®è£ ããããŸããŸãªã·ããªãªã§ãã¹ãããããšã ãšæããŸãã
Widget
ããæ¥ãŸããããŠããã¹ããªãŒã ã¯æéãšãšãã«å€åããå¯èœæ§ããããã«å¯ŸããŠåã ã®ã±ãŒã¹ããã¹ãããŸãã
ããã¯çŸåšã Property
ãŸãã¯onDispose
解決ã§ããŸããã
@esDotDev ãèŠæ±ãããèªã¿ããããšå ç¢æ§ã®å©ç¹ããåæã§ããŸããïŒ èª°ãããããã®èªã¿ããããšå ç¢æ§ã®å©ç¹ãåããAnimationControllerãåŠçããææ¡ãããå Žåãããã§å®äºã§ããïŒ
@rrousselGitããããã£ã¯åé¡ã解決ããªããšåã«èšã£ãããã«ãç§ã¯ããããã£ãæ¯æããŠããŸããã ãããã誰ããStreamBuilderãè¡ããã¹ãŠã®ããšããã€ã³ãã³ããªãã§å®è¡ãããœãªã¥ãŒã·ã§ã³ãäœæãããšããããããã¯ããã§ããããïŒ ããªãã¯å¹žãã«ãªããŸããïŒ
ãããã誰ããStreamBuilderãè¡ããã¹ãŠã®ããšããã€ã³ãã³ããªãã§å®è¡ãããœãªã¥ãŒã·ã§ã³ãäœæãããšããããããã¯ããã§ããããïŒ ããªãã¯å¹žãã«ãªããŸããïŒ
ããããããã§ã
ãã¡ããããã®ãœãªã¥ãŒã·ã§ã³ãä»ã®ãœãªã¥ãŒã·ã§ã³ãšæ¯èŒããå¿ èŠããããŸãã ããããããã¯èš±å®¹ã¬ãã«ã«éããã§ãããã
@esDotDev ãèŠæ±ãããèªã¿ããããšå ç¢æ§ã®å©ç¹ããåæã§ããŸããïŒ
äŸåé¢ä¿ãšã©ã€ããµã€ã¯ã«ã®åšãã®å®åæãå®å šã«ã«ãã»ã«åã§ãããšããç¹ã§ã®å ç¢æ§ã NSã æ¯åfetchUserã«éç¥ããå¿ èŠã¯ãããŸããããããããIDãå€æŽããããšãã«åæ§ç¯ããå¿ èŠããããå éšã§åæ§ç¯ããããšãç¥ã£ãŠããŸãã 芪ãŠã£ãžã§ãããç Žæ£ããããã³ã«ãã¢ãã¡ãŒã·ã§ã³ã«ããèªäœãç Žæ£ããããã«æ瀺ããå¿ èŠã¯ãããŸããïŒããããã£ããã®tbhãå®è¡ã§ãããã©ããã¯å®å šã«ã¯ç解ããŠããŸããïŒã ããã«ãããéçºè ã¯ã³ãŒãããŒã¹å šäœã§ããŒãã¿ã¹ã¯ãééããããšããªããªããŸãïŒçŸåšimoã䜿çšããBuilderã䜿çšããäž»ãªå©ç¹ã®1ã€ïŒ
èªã¿ãããã¯ãã€ã³ãã³ããããŠããªã1è¡ã®ã³ãŒãã§ã¹ããŒããã«ãªãã®ãååŸã§ãããã®å€æ°ãæã¡äžããããŠã¯ã£ãããšèŠããããšã§ãã
@esDotDev誰ããããããã®èªã¿ããããšå ç¢æ§ã®å©ç¹ãåããAnimationControllerãåŠçããææ¡ãããå Žåãããã§å®äºã§ããïŒ
ç¹ã«AnimationControllerãæå³ããå Žåã¯ãããŸããã AnimationController / FocusController / TextEdiitingControllerã®ãããªãªããžã§ã¯ããæå³ããå Žåã¯ãã¯ãã
æ確ã§ã¯ãªãå®çŸ©ããã寿åœãæã€å€ãè¿ãé¢æ°ã®ãããªAPIãæã€ããšã¯
ããã¯éèŠãªèª€è§£ã ãšæããŸãã ããã¯ã¯å®çŸ©äžãµãã¹ããŒãã§ãããããããã¯ã®åç¶æéã¯æ確ã§ãã ãããã¯ãããããã䜿çšãããåœã®åç¶æéäžãåžžã«ååšããŸãã å®éã«ã¯ãã以äžæ確ã«ããããšã¯ã§ããŸããã æ§æã¯å¥åŠã§ãªãã¿ã®ãªããã®ãããããŸãããã確ãã«æ確ããæ¬ ããŠããŸããã
TweenAnimationBuilderïŒïŒã®åç¶æéãæ確ã§ããã®ãšåæ§ã§ãã 芪ãããªããªããšæ¶ããŸãã åãŠã£ãžã§ãããšåæ§ã«ããããã¯åã®ç¶æ ã§ãã ãããã¯å®å šã«ç¬ç«ããç¶æ ã®ãã³ã³ããŒãã³ããã§ãããç°¡åã«çµã¿ç«ãŠãŠåå©çšã§ããŸãããŸãããã°ã§ã¯ãªãæ©èœãšããŠå®£èšãããç¶æ ã«èªç¶ã«ãã€ã³ãããå¿ èŠããããããæ瀺çã«ã©ã€ãã¿ã€ã ã管çããŸããã
@esDotDev
NS
ãã£ãšå ·äœçã«ã§ããŸããïŒ ïŒãããããã¹ãŠã®ããŒã¹ãã«ããŒãããã¢ã¢ããªã±ãŒã·ã§ã³ãèãåºãããšãææ¡ããçç±ã§ãããããè¡ãã«ã¯ããããæåã®æ¹æ³ã ãšåŒãç¶ãèããŠããŸããïŒæ§æãå€æŽãããŠèªåçã«ç Žæ£ãããªãéããã€ãã·ã£ã©ã€ã¶ãŒãåŒã³åºã以å€ã«éèŠãªæ©èœã¯ãããŸããïŒãã¹ãèŠçŽ ãç Žæ£ããããšãã«å²ãåœãŠããããªãœãŒã¹ïŒ
TextEdiitingControllerã®ãããªãªããžã§ã¯ã
ãã£ãšå ·äœçã«ã§ããŸããïŒ TextEditingControllerã¯AnimationControllerãããäœããã®åœ¢ã§è€éã§ããïŒ
@rrousselGit
ãããã誰ããStreamBuilderãè¡ããã¹ãŠã®ããšããã€ã³ãã³ããªãã§å®è¡ãããœãªã¥ãŒã·ã§ã³ãäœæãããšããããããã¯ããã§ããããïŒ ããªãã¯å¹žãã«ãªããŸããïŒ
ããããããã§ã
ããã¯ãã€ã³ãã³ããªãã§StreamBuilderãå®è¡ãããã¹ãŠã®ããšãå®è¡ãããœãªã¥ãŒã·ã§ã³ã§ãã
Widget build(context) {
var result = Text('result:');
var builder1 = (BuildContext context, AsyncSnapshot<int> snapshot) {
return Row(children: [result, Text(snapshot.data)]);
};
result = StreamBuilder(stream: _stream1, builder: builder1);
var builder2 = (BuildContext context, AsyncSnapshot<int> snapshot) {
return Column(children: [result, Text(snapshot.data)]);
};
result = StreamBuilder(stream: _stream2, builder: builder2);
}
ãã ããããã¯ä»ã®å¶çŽã«éåããŠãããšæããŸãã ã ãããããç§ãã¡å šå¡ãåæã§ãããã®ã欲ããã®ã§ããããã¯ãåé¡ã解決ããããšããåã«ãåé¡ã®å®å šãªèª¬æã§ãã
ããã¯ããã«ããŒã@Hixieã«æã£ãŠããã®ãšåãå¶çŽã§ããããã以äžã®ããšã誰ãæ±ããŠããŸããã ãã«ããŒã¯widget.whateverã«çµã³ä»ããããšãã§ããŸãããã«ããŒã¯ããŠã£ãžã§ããããªãŒã®ã³ã³ããã¹ãã§å¿ èŠãªå éšç¶æ ãå®å šã«ç®¡çã§ããŸãã ããã¯ããã¯ãã§ãããã¹ãŠã§ããã誰ãããã€ã¯ãã¹ããŒããŸãã¯ããªãããããåŒã³ãããã®ãæ±ããŠãããã¹ãŠã§ãã
ãã£ãšå ·äœçã«ã§ããŸããïŒ TextEditingControllerã¯AnimationControllerãããäœããã®åœ¢ã§è€éã§ããïŒ
ãããããã ããinit / disposeã§ç°ãªãåŠçãå®è¡ããå¯èœæ§ããããŸããããã§ãªãå Žåã¯ãç°ãªãããããã£ã«ãã€ã³ããããããããã®ç¹å®ã®ãã€ã©ãŒãã¬ãŒããã«ãã»ã«åããå¿ èŠããããŸãã
@esDotDevã§ã¯ããã«ããŒãšåããã®ãå¿ èŠã§ãããã€ã³ãã³ãã¯ãªãã1è¡ã§ïŒãããããã«ããŒã®ã³ãŒã«ããã¯èªäœãé€ããŠïŒïŒ ç§ãæçš¿ããã°ããã®äŸïŒhttps://github.com/flutter/flutter/issues/51752#issuecomment-671004483ïŒã¯ãä»æ¥ã®ãã«ããŒã§ãããè¡ã£ãŠããã®ã§ããããããã以äžã®è¿œå ã®å¶çŽããããŸããïŒ
ïŒFWIWããã«ããŒããŸãã¯ãã«ããŒã®ãããªãã®ã§ã¯ãªãã1è¡ã§ãåããŒã¿åã«ç¬èªã®ãã«ããŒãäœæããå¿ èŠããããããè¯ã解決çã§ã¯ãªããšæããŸãããã®å Žã§ãã«ãããã ãã®è¯ãæ¹æ³ã¯ãããŸããã ãïŒ
ïŒFWIWããã«ããŒããŸãã¯ãã«ããŒã®ãããªãã®ã§ã¯ãªãã1è¡ã§ãåããŒã¿åã«ç¬èªã®ãã«ããŒãäœæããå¿ èŠããããããè¯ã解決çã§ã¯ãªããšæããŸãããã®å Žã§ãã«ãããã ãã®è¯ãæ¹æ³ã¯ãããŸããã ãïŒ
ãããäœãæå³ããã®ãããããŸããã èšãæããŠããããŸããïŒ ð
ã¢ãã¡ãŒã·ã§ã³çšã®AnimationBuilderãšã¹ããªãŒã çšã®StreamBuilderãªã©ãäœæããå¿ èŠããããŸãã StatefulWidgetãäœæãããšãã«ããã«ããŒã1ã€ã ãæã£ãŠããæ°ãããã«ããŒãååŸããæ¹æ³ãç Žæ£ããæ¹æ³ãããŒã¿ãååŸããæ¹æ³ããªã©ãšèšã代ããã«ã
ãã ããããã¯ä»ã®å¶çŽã«éåããŠãããšæããŸãã ã ãããããç§ãã¡å šå¡ãåæã§ãããã®ã欲ããã®ã§ããããã¯ãåé¡ã解決ããããšããåã«ãåé¡ã®å®å šãªèª¬æã§ãã
ããã¯ãèªã¿åãå¯èœãªã³ãŒãã®èŠæ±ã«ããªãæããã«éåããŠãããšæããŸãããããæçµçãªç®æšã§ããããã§ãªãå Žåã¯ã100äžåã®ç¹å¥ã«åæå®ããããã«ããŒã䜿çšããemãæ°žä¹ ã«ãã¹ãããŠã1æ¥ãšåŒã³ãŸãã
èŠæ±ãããŠããã®ã¯æ¬¡ã®ãããªãã®ã ãšæããŸãïŒç§ã«èããŠãã ãããç§ã¯ããŸã䜿çšããŸãããStreamsãããŸã䜿çšããŸããïŒïŒ
Widget build(context) {
var snapshot1 = get AsyncSnapshot<int>(stream1);
var snapshot2 = get AsyncSnapshot<int>(stream2);
return Column(children: [Text(snapshot1.data), Text(snapshot2.data)]);
}
ããããã¹ãŠã®ã³ãŒãã§ãã ã¹ããªãŒã ãç§ãã¡ã®ããã«äœæãããã¹ããªãŒã ãç§ãã¡ã®ããã«ç Žæ£ãããç§ãã¡ã足ã§èªåèªèº«ãæã€ããšãã§ãããã³ãŒããã¯ããã«èªã¿ããããªãã®ã§ããã以äžäœããããŸããã
ã¢ãã¡ãŒã·ã§ã³çšã®AnimationBuilderãšã¹ããªãŒã çšã®StreamBuilderãªã©ãäœæããå¿ èŠããããŸãã
ããã¯åé¡ã§ã¯ãªããšæããŸãã RestorableInt vs RestorableString vsRestorableDoubleã¯ãã§ã«ãããŸã
ãããŠãžã§ããªãã¯ã¯ããã解決ããããšãã§ããŸãïŒ
GenericBuilder<Stream<int>>(
create: (ref) {
var controller = StreamController<int>();
ref.onDispose(controller.close);
return controller.stream;
}
builder: (context, Stream<int> stream) {
}
)
åæ§ã«ããããæ¬åœã«åé¡ã§ããå ŽåãFlutterãŸãã¯Dartã«Disposable
ã€ã³ã¿ãŒãã§ãŒã¹ãå«ããããšãã§ããŸãã
@esDotDev
èŠæ±ãããŠããã®ã¯æ¬¡ã®ãããªãã®ã ãšæããŸãã
ããã¯ãä»ã®äººããªã¹ãããããªãåççãªå¶çŽïŒ@Rudikszãªã©ïŒã®ããã€ãã«éåããŸããã€ãŸããbuildã¡ãœããã®åŒã³åºãäžã«åæåã³ãŒããçºçããªãããšãä¿èšŒããŸãã
@rrousselGit
ããã¯åé¡ã§ã¯ãªããšæããŸãã RestorableInt vs RestorableString vsRestorableDoubleã¯ãã§ã«ãããŸã
ãããŠãAnimationBuilderãStreamBuilderãªã©ããããŸãã ã©ã¡ãã®å Žåãæ®å¿µã§ãã
GenericBuilder
ããã¯ç§ãäžåç£ã«ææ¡ãããã®ãšäŒŒãŠããŸãããããã§ããªãã®æžå¿µãç解ããå Žåãããªãã¯åé·ããããšä¿¡ããŠããŸããã
以åãStreamBuilderãå®è¡ãããã¹ãŠã®ããšãå®è¡ãããœãªã¥ãŒã·ã§ã³ã誰ããäœæãããšããŠããã€ã³ãã³ãããªããã°ãæºè¶³ããã ãããšãã£ããããŸããã ããªãã¯ãããããããšããç§ã®è©Šã¿ã«ã€ããŠã³ã¡ã³ãããŠããŸããïŒhttps://github.com/flutter/flutter/issues/51752#issuecomment-671004483ïŒã ãã®è§£æ±ºçã«æºè¶³ããŠããŸããïŒ
@esDotDev
èŠæ±ãããŠããã®ã¯æ¬¡ã®ãããªãã®ã ãšæããŸãã
ããã¯ãä»ã®äººããªã¹ãããããªãåççãªå¶çŽïŒ@Rudikszãªã©ïŒã®ããã€ãã«éåããŸããã€ãŸããbuildã¡ãœããã®åŒã³åºãäžã«åæåã³ãŒããçºçããªãããšãä¿èšŒããŸãã
ãã®ã³ãŒãããã«ããããŠããããšã¯éèŠã§ã¯ãããŸããã éèŠãªã®ã¯
ããã¯é©ãã¹ãããšã§ãïŒ
AsyncSnapshot<int> snapshot1 = createLifecycleState(widget.stream1);
AsyncSnapshot<int> snapshot2 = createLifecycleState(widget.stream2);
AniamtorController animator = createLifecycleState(duration: Duration(seconds: 1), (a)=>a.forward());
Widget build(context) {
return Opacity(opacity: animator.value, child: Column(children: [Text(snapshot1.data), Text(snapshot2.data)]));
}
ãŸãã¯ãç°¡æœã§ã¯ãããŸãããããã«ããŒã䜿çšãããããã¯ããã«èªã¿ããããçŽæ¥å®è¡ãããããåé·ã§ãšã©ãŒãçºçãã«ãããªããŸãã
AsyncSnapshot<int> stream1;
AsyncSnapshot<int> stream2;
<strong i="18">@override</strong>
void initState(){
snapshot1 = createLifecycleState(widget.stream1);
snapshot2 = createLifecycleState(widget.stream2);
super.initState();
}
Widget build(context) {
return Column(children: [Text(snapshot1.data), Text(snapshot2.data)]);
}
ãªãåé·æ§ã«æ»ãç¶ããã®ãããããŸããã
ç§ã¯ãããã¯åé¡ã§ã¯ãªããåé¡ã¯åå©çšæ§ãå¯èªæ§ãæè»æ§ã§ãããšäœåºŠãæ確ã«è¿°ã¹ãŸããã
ãœãªã¥ãŒã·ã§ã³https://github.com/flutter/flutter/issues/51752#issuecomment-671000137ãšãã¹ãã±ãŒã¹https://github.com/flutter/flutter/issues/51752#issuecommentãè©äŸ¡ããããã®ã°ãªãããäœæããŸãã- 671002248
以åãStreamBuilderãå®è¡ãããã¹ãŠã®ããšãå®è¡ãããœãªã¥ãŒã·ã§ã³ã誰ããäœæãããšããŠããã€ã³ãã³ãããªããã°ãæºè¶³ããã ãããšãã£ããããŸããã ããªãã¯ç§ã®è©Šã¿ã«ã€ããŠã³ã¡ã³ãããŠããŸããïŒïŒ51752ïŒã³ã¡ã³ãïŒïŒã ãã®è§£æ±ºçã«æºè¶³ããŠããŸããïŒ
ããã¯ã蚱容å¯èœãªæå°ã¬ãã«ã®æè»æ§ã«éããŸãã
https://github.com/flutter/flutter/issues/51752#issuecomment -671000137ã«åŸã£ãŠè©äŸ¡ãããšã次ã®ããã«ãªããŸãã
Widget build(context) {
// this builder is not highlighted, but you can hover over it to see how often it rebuilds, how heavy were those rebuilds, and when was the last rebuild
var snapshot1 = keyword StreamBuilder(stream1);
// this builder will be highlighted because it triggered the rebuild
var constraints = keyword LayoutBuilder();
// <-- I had a breakpoint here and parent constraint changed, breakpoints got reached.
return Column(children: [Text(snapshot1.data), Text(snapshot2.data)]);
}
ãŸãã @ Hixie
ããã¯ãä»ã®äººããªã¹ãããããªãåççãªå¶çŽïŒ@Rudikszãªã©ïŒã®ããã€ãã«éåããŸããã€ãŸããbuildã¡ãœããã®åŒã³åºãäžã«åæåã³ãŒããçºçããªãããšãä¿èšŒããŸãã
* Buildersã䜿çšããŠããã§ã«æé»çã«ãããè¡ã£ãŠããŸãã ãããããã€ã³ãã³ãããããã«å¿ èŠãªã®ã¯ã·ã³ã¿ãã¯ã¹ã·ã¥ã¬ãŒã ãã§ãã async / awaitãfuturesã«ãã䌌ãŠãããšæããŸãã
@esDotDevããªãã説æããããšã¯ãç§ã以åã«ããããã£ã§ææ¡ãããã®ãšéåžžã«äŒŒãŠããŸãïŒããšãã°ãhttpsïŒ//github.com/flutter/flutter/issues/51752#issuecomment-664787791ãŸãã¯https://github.com/flutter/flutter/ãåç §ããŠãã ããïŒã issues / 51752ïŒissuecomment-667737471ïŒã ãã®çš®ã®ãœãªã¥ãŒã·ã§ã³ãããã±ãŒãžãšããŠäœæãããã®ã劚ãããã®ã¯ãããŸããïŒ ã€ãŸãããã®çš®ã®æ©èœã䜿çšã§ããããã«ããã«ã¯ãã³ã¢ãã¬ãŒã ã¯ãŒã¯ã«ã©ã®ãããªå€æŽãå ããå¿ èŠããããŸããïŒ
@rrousselGit Shawnãšåãããã«ãåãããšããé¡ãããŸãã çŸåšã®StreamBuilderæ©èœãšããŒãºãæºãããã®ãšã®å¯äžã®éããç°ãªãæ§æã§ããå Žåããã®ãããªæ©èœã䜿çšã§ããããã«ããããã«ã³ã¢æ§æã«å¿ èŠãªãã®ã¯äœã§ããïŒ å¥œã¿ã®æ§æãäœæããŠããã䜿çšããã ãã§ã¯äžååã§ããããïŒ
ç§ãããªãã®ã°ãªããã§æ±ããŠããåé¡ã¯ããããŸã§ã®ãœãªã¥ãŒã·ã§ã³ã«ãããé©çšãããšããããåŸããããšããããšã§ããããã¯ãããªããåŸããã®ãšã¯éåžžã«ç°ãªããšæããŸãã
StatefulWidget
ããããã£ã®ããªãšãŒã·ã§ã³
ãã«ããŒã®ããªãšãŒã·ã§ã³
ããã¯ã®ãããªãœãªã¥ãŒã·ã§ã³
ãªãåé·æ§ã«æ»ãç¶ããã®ãããããŸããã
ç§ã¯ãããã¯åé¡ã§ã¯ãªããåé¡ã¯åå©çšæ§ãå¯èªæ§ãæè»æ§ã§ãããšäœåºŠãæ確ã«è¿°ã¹ãŸããã
ç³ãèš³ãããŸããããããããã£ãåé·ããããšèšã£ãã®ã¯èª°ãªã®ããæãåºããŸããã§ããã ããã§ããããªãã®æžå¿µã¯ã以åã«ãªã¹ããããŠããªãã£ãæ°ãããŠãŒã¹ã±ãŒã¹ãããããããåŠçãããªãã£ããšããããšã§ããããããããã£ãæ¡åŒµããŠãã®ãŠãŒã¹ã±ãŒã¹ãåŠçããã®ã¯ç°¡åã ãšæããŸãïŒç§ã¯è©ŠããŠããŸããããèŠä»¶ã調æŽããããšãã«ç¹°ãè¿ãç¹°ãè¿ãã®ã§ã¯ãªããåé¡ãäžåºŠã«è§£æ±ºã§ããããã«ãæ確ãªãã¢ã¢ããªãã§ãããŸã§åŸ ã€æ¹ãããããã§ãïŒã
@szotp
- ãã®æ©èœIMOã¯ãããšãã°LayoutBuilderãå«ããã¹ãŠã®ãã«ããŒãŠã£ãžã§ããã«æ¡åŒµã§ããŸãã
LayoutBuilderã¯ãã»ãšãã©ã®ãã«ããŒã§ããFWIWãšã¯éåžžã«ç°ãªããŠã£ãžã§ããã§ãã ãããŸã§ã«èª¬æããææ¡ã¯ãããããLayoutBuilderã®ãããªåé¡ã«ã¯æ©èœããŸããããŸããã³ã¡ã³ãã®åã«èª¬æããèŠä»¶ã«ã¯ãLayoutBuilderãå«ãŸããŠããŸããã ãã®æ°æ©èœã䜿çšããŠLayoutBuilderãåŠçããå¿ èŠãããå Žåã¯ãç¥ã£ãŠããããšãéèŠã§ãã @TimWhitingã䜿çšããŠãææ¡ã®ããŒã¹ãšãªããµã³ãã«ã¢ããªã«ãäŸãšããŠã¬ã€ã¢ãŠããã«ããŒãå«ãŸããŠããããšã確èªããããšããå§ãããŸãã
- 10xã³ã³ãããŒã©ãŒãäœæããŠåæ§ç¯ã®ããã«ãªãŒãã«æž¡ãããšãã§ããããã«ããªã¹ãã³ã°ãç¡å¹ã«ããæ¹æ³ãå¿ èŠã§ãããŸãã¯ããã©ãã¿ãŒã¯ãããªãŒã®ã©ã®éšåããã«ããŒã«ãã£ãŠååŸãããå€ã䜿çšããããäœããã®æ¹æ³ã§ç¥ãå¿ èŠããããŸãã
ãããäœãæå³ããã®ãæ£ç¢ºã«ã¯ããããŸããã ç§ã®ç¥ãéããããã¯ãªã¹ããŒãšãã«ããŒã䜿çšããŠä»æ¥è¡ãããšãã§ããŸãïŒããšãã°ãåã«åŒçšããã¢ããªã§ValueListenableBuilderã䜿çšããŠããããæ£ç¢ºã«å®è¡ããŸãïŒã
ããã¯ãä»ã®äººããªã¹ãããããªãåççãªå¶çŽïŒ@Rudikszãªã©ïŒã®ããã€ãã«éåããŸããã€ãŸããbuildã¡ãœããã®åŒã³åºãäžã«åæåã³ãŒããçºçããªãããšãä¿èšŒããŸãã
* Buildersã䜿çšããŠããã§ã«æé»çã«ãããè¡ã£ãŠããŸãã
ç§ã¯ãããæ£ç¢ºã ãšã¯æããŸããã ãã«ããŒã«ãã£ãŠç°ãªããŸãããinitStateãdidChangeDependenciesãdidUpdateWidgetãããã³ãã«ãããžãã¯ãåé¢ããã®ã«éåžžã«èŠåŽãããã®ããããããå€æŽå 容ã«åºã¥ããŠåãã«ããå®è¡ããããã«å¿ èŠãªã³ãŒãã¯æå°éã§ãã ããšãã°ãValueListenableBuilderã¯æåã«äœæããããšãã«ã®ã¿ãªã¹ããŒãç»é²ãããã®ãã«ããŒã¯ããã«ããŒã®èŠªãŸãã¯initStateãåå®è¡ããã«åå®è¡ã§ããŸãã ããã¯ããã¯ãã§ããããšã§ã¯ãããŸããã
@esDotDevããªãã説æããããšã¯ãç§ã以åã«Propertyã§ææ¡ãããã®ãšéåžžã«äŒŒãŠããããã«èãããŸãïŒããšãã°ã ïŒ51752ïŒã³ã¡ã³ãïŒãŸãã¯ïŒ51752ïŒã³ã¡ã³ãïŒãåç §ïŒã
ç§ãæ£ããç解ããŠããã°ãUserIdã®DidDependancyChangeãèªåçã«åŠçããUserProperty
ã AnimationProperty
ããŸãã¯ãã®ã¿ã€ãã®init / update / disposeãåŠçããããã«å¿
èŠãªãã®ä»ã®ããããã£ãäœæã§ããŸããïŒ ãããªããããã¯ç§ã«ã¯ããããã§ãã æãäžè¬çãªãŠãŒã¹ã±ãŒã¹ã¯ããã«äœæã§ããŸãã
ç§ãæšãŠãå¯äžã®ãã®ã¯ãããã®æªæ¥ã®ãã«ããŒã§ãã ããããããã¯ããªããéžãã äŸã«ãããã®ã ãšæããŸããïŒ
ããšãã°ããããäœæã§ããŸããïŒ
class _ExampleState extends State<Example> with PropertyManager {
AnimationProperty animProp1;
AnimationProperty animProp2;
<strong i="15">@override</strong>
void initProperties() {
super.initProperties();
anim1= register(anim1, AnimationProperty (
AnimationController(duration: Duration(seconds: 1)),
initState: (animator) => animator.forward()
// Not dealing with updates or dispose here, cause AnimationProperty handles it
));
anim2 = register(anim2, AnimationProperty(
AnimationController(duration: Duration(seconds: 2))..forward(),
));
}
<strong i="16">@override</strong>
Widget build(BuildContext context) {
return Column(children: [
FadeTransition(opacity: anim1, child: ...),
FadeTransition(opacity: anim2, child: ...),
])
}
}
ãããããªããããã¯å®å šã«LGTMã§ãïŒ ãã¬ãŒã ã¯ãŒã¯ãžã®è¿œå ã«é¢ããŠã¯ãããããã¡ãŒã¹ãã¯ã©ã¹ã®æ§æçã¢ãããŒãã«ææ Œãããå¿ èŠããããïŒã€ãŸãã1幎ã»ã©ã§äžè¬çã«ãªãïŒããŸãã¯éçºè ã®1æ¡ã®å²åã®ãã©ã°ã€ã³ãšããŠååšãããã©ããã®ã±ãŒã¹ã§ãã䜿çšããã
ããç°¡æœãªæ§æã§ãåé·ã§ïŒãããã«ïŒïŒãšã©ãŒãçºçããããäŸãæŽæ°ã§ããããã«ãããã©ãããåé¡ã«ãªããŸãã ããããã£ãæåã§åæããæåã§disposeïŒïŒãå®è¡ããå¿ èŠããããšããã°ãèªç¥çè² è·ãçºçããŸãã
Imoéçºè ããé©åãªdidUpdateãdisposeãdebugFillPropertiesã䜿çšããŠã¢ãã¡ãŒã¿ãŒã䜿çšã§ããã°ãããã«ã€ããŠäºåºŠèããå¿ èŠã¯ãããŸããïŒTweenAnimationBuilderã䜿çšãããšããšãŸã£ããåãããã«ããããç§ãã¡ãæšå¥šããäž»ãªçç±ã§ãïŒããã¹ãŠã®éçºè ã¯ãããã©ã«ãã§ã¢ãã¡ãŒã¿ãŒãæåã§ç®¡çããããã䜿çšããŸãïŒã
ãããããªããããã¯å®å šã«LGTMã§ãïŒ ãã¬ãŒã ã¯ãŒã¯ãžã®è¿œå ã«é¢ããŠã¯ãããããã¡ãŒã¹ãã¯ã©ã¹ã®æ§æçã¢ãããŒãã«ææ Œãããå¿ èŠããããïŒã€ãŸãã1幎ã»ã©ã§äžè¬çã«ãªãïŒããŸãã¯éçºè ã®1æ¡ã®å²åã®ãã©ã°ã€ã³ãšããŠååšãããã©ããã®ã±ãŒã¹ã§ãã䜿çšããã
Property
ãããã«äºçŽ°ãªããšããèãããšããã®ã¹ã¿ã€ã«ã奜ããªäººãžã®ç§ã®æšå¥šäºé
ã¯ãç¬èªã®ã¹ã¿ã€ã«ãäœæãïŒããã圹ç«ã€å Žåã¯ç§ã®ã³ãŒãããå§ããŠïŒãé©åãšæãããå Žåã¯ã¢ããªã§çŽæ¥äœ¿çšããŠèª¿æŽããããšã§ãã圌ãã®ããŒãºã«å¯Ÿå¿ããããã«ã å€ãã®äººãæ°ã«å
¥ã£ããããã±ãŒãžã«ããããšãã§ããŸãããäºçŽ°ãªããšã§ããã³ãŒãã«ã³ããŒããŠå¿
èŠã«å¿ããŠèª¿æŽããã®ãšæ¯ã¹ãŠãã©ãã ãæçãã¯ããããŸããã
ç§ãæšãŠãå¯äžã®ãã®ã¯ãããã®æªæ¥ã®ãã«ããŒã§ãã ããããããã¯ããªããéžãã äŸã«ãããã®ã ãšæããŸããïŒ
@rrousselGitãæäŸããäŸã«å¯ŸåŠããããšããŠããŸããã ååãšããŠãããã¯äœã«ã§ãæ©èœããããã«é©åãããããšãã§ããŸãã
ããšãã°ããããäœæã§ããŸããïŒ
æ¯ååŒã³åºãã®ã§ã¯ãªããAnimationControllerã³ã³ã¹ãã©ã¯ã¿ãŒãåŒã³åºãããã¯ããŒãžã£ãŒã«ç§»åããå¿
èŠããããŸããããã¯ãããããªããŒãäžã«æ°ããã¯ããŒãžã£ãŒãååŸããããã«initProperties
ãåŒã³åºãããããã§ãããéåžžã¯äœæããããªãããã§ããããããªããŒãäžã®æ°ããã³ã³ãããŒã©ãŒïŒã¢ãã¡ãŒã·ã§ã³ããªã»ãããããªã©ïŒã ããããã¯ãããã以å€ã¯åé¡ãªãããã§ãã AnimationController
ã³ã³ã¹ãã©ã¯ã¿ãŒåŒæ°ãåãããããã䜿çšããŠæ£ããåŠçãè¡ãAnimationControllerProperty
ãäœæããããšãã§ããŸãïŒããšãã°ãããããªããŒãã®æéãå€æŽãããå Žåã¯æŽæ°ããŸãïŒã
Imoéçºè ããé©åãªdidUpdateãdisposeãdebugFillPropertiesã䜿çšããŠã¢ãã¡ãŒã¿ãŒã䜿çšã§ããã°ãããã«ã€ããŠäºåºŠèããå¿ èŠã¯ãããŸããïŒTweenAnimationBuilderã䜿çšãããšããšãŸã£ããåãããã«ããããç§ãã¡ãæšå¥šããäž»ãªçç±ã§ãïŒããã¹ãŠã®éçºè ã¯ãããã©ã«ãã§ã¢ãã¡ãŒã¿ãŒãæåã§ç®¡çããããã䜿çšããŸãïŒã
éçºè ã«ããã«ã€ããŠèããããªãããšã«ã€ããŠã®ç§ã®å¿é ã¯ãç©äºããã€å²ãåœãŠãããŠåŠåããããã«ã€ããŠèããªããšãå¿ ãããå¿ èŠã§ã¯ãªãå€ãã®ãã®ãå²ãåœãŠãããå¿ èŠã®ãªãããžãã¯ãå®è¡ãããããå¯èœæ§ãé«ããªãããšã§ããå®è¡ããå¿ èŠãããããŸãã¯ã³ãŒãã®å¹çãäœäžãããä»ã®ããšãè¡ãå¿ èŠããããŸãã ãããããããããã©ã«ãã®æšå¥šã¹ã¿ã€ã«ã«ããããšãèºèºããçç±ã®1ã€ã§ãã
AnimationControllerã³ã³ã¹ãã©ã¯ã¿ãŒåŒæ°ãåãåãããããã䜿çšããŠæ£ããåŠçãè¡ãAnimationControllerPropertyãäœæããããšãã§ããŸãïŒããšãã°ãããããªããŒãã®æéãå€æŽãããå Žåã¯æŽæ°ããŸãïŒã
@Hixieã«æè¬ã
éçºè ããããã®ããšã決ããŠèããã¹ãã§ã¯ãªãããšã瀺åããŠããããã§ã¯ãããŸãããã99ïŒ ã®ãŠãŒã¹ã±ãŒã¹ã§ã¯ããããã®ããšã¯ã»ãšãã©ã®å Žåã䜿çšãããŠããStatefulWidgetã«ãã€ã³ããããŠããããã以å€ã®ããšãè¡ããšããã§ã«äžéã®éçºè ã®é åã«ç§»åããŠãããšæããŸãã
ç¹°ãè¿ããŸããããããçã®AnimatorControllerãããTweenAnimationBuilderãæšå¥šããããšãšæ ¹æ¬çã«ã©ã®ããã«éãã®ãããããŸããã ããã¯ããã®ããã«ãã®åçŽãã€ããå ç¢ã«ãããè¡ãããã®åŸãïŒãããäœããããéåžžã¯ïŒããªããç¶æ ããããå Žåã¯ãå®å šã«å«ãŸããŠãã/ãã®ä»ã®ç¶æ ã§ç®¡çããããšãåºæ¬çãªèãæ¹ã§ãã
ãã®æç¹ã§ãé»è©±ããããããŸããŸãªå©å®³é¢ä¿è
ãšè©±ãåãå¿
èŠããããŸãã
åã質åã«äœåºŠãçããŠããã®ã§ããã®è°è«ã¯é²ãã§ããªãããã§ãã
éåžžã«å€ãã®è°è«ããªããããã®ãããªé·ãè°è«ã®åŸããã«ããŒãStatefulWidgetãšæ¯èŒããŠééããåé¿ããªãããŸãã¯ããã¯ãçã®StatefulWidgetsãããåå©çšå¯èœã§ã¯ãªããšäž»åŒµã§ããæ¹æ³ãããããŸããã
ããã¯ããã¹ãŠã®äž»èŠãªå®£èšåãã¬ãŒã ã¯ãŒã¯ïŒReactãVueãSwift UIãJetpack ComposeïŒããã®åé¡ããã€ãã£ãã«è§£æ±ºããæ¹æ³ãæã£ãŠããããšãèãããšãç¹ã«ã€ã©ã€ã©ããŸãã
Flutterã ãããã®åé¡ã®æ€èšãæåŠããŠããããã§ãã
@esDotDev IMHOãAnimationBuilderãTweenAnimationBuilderããŸãã¯ValueListenableBuilderã䜿çšããäž»ãªçç±ã¯ããã¹ããŠã£ãžã§ããã®æ®ãã®éšåãåæ§ç¯ããã«ãå€ãå€æŽããããšãã«ã®ã¿åæ§ç¯ããããã§ãã ããã¯ããã©ãŒãã³ã¹ã®åé¡ã§ãã åé·æ§ãã³ãŒãã®åå©çšã«ã€ããŠã§ã¯ãããŸããã ã€ãŸãããããã®çç±ã§åœ¹ç«ã€ãšæãããå Žåã¯ããããã®çç±ã§ã䜿çšã§ããŸãããå°ãªããšãç§ã«ãšã£ãŠã¯ããããäž»ãªãŠãŒã¹ã±ãŒã¹ã§ã¯ãããŸããã ããã¯ãŸããããããã£ïŒãŸãã¯ããã¯ïŒãããªãã«äžããªããã®ã§ããããŸãã ãããã䜿çšãããšãäœããå€æŽããããšãã«_entire_ãŠã£ãžã§ãããåæ§ç¯ããããšã«ãªããããã©ãŒãã³ã¹ã«æªåœ±é¿ãåãŒããŸãã
@rrousselGit
Flutterã ãããã®åé¡ã®æ€èšãæåŠããŠããããã§ãã
ç§ã¯ä»é±æ«ãæåéãäœæéãèªåã®æéãéãããŸããããã以åã®Googleã®æéã¯èšããŸã§ããªãããã®åé¡ãæ€èšããèãããã解決çã説æãã解決ããããšããŠããããšãæ£ç¢ºã«åŒãåºããããšããŠããŸãã äœãåé¡ãªã®ãç解äžè¶³ãšæ··åããªãã§ãã ããã ç¹ã«ããããåé²ãããããã«ã§ããæåã®ããšããã§ã«èª¬æããå ŽåïŒãåé·ãããããŸãã¯é£ããããããã¹ãŠã®ç¶æ ããžãã¯ãåãããã¢ã¢ããªãäœæããåé¡ã®ã¿ã€ãã«ãåŒçšããåå©çšããïŒããã®ãã°ã«é¢ããä»ã®äººãã¿ã¹ã¯ãšããŠåŒãåããŠãããããªãã¯åå ãæåŠããŠããŸãã
The main reason IMHO to use an AnimationBuilder or TweenAnimationBuilder or ValueListenableBuilder is that they rebuild only when the value changes, without rebuilding the rest of their host widget. It's a performance thing.
é¢çœãã ç§ãã¡ã«ãšã£ãŠããã®ãããªå°ããªåæ§ç¯ãä¿åããããšã«ããããã©ãŒãã³ã¹ã®åäžãå®éã«æž¬å®ãŸãã¯èŠ³å¯ããããšã¯ãããŸããã 倧èŠæš¡ãªã¢ããªã³ãŒãããŒã¹ã§ã¯ãã³ãŒããç°¡æœã§èªã¿ããããæ°é±éããšã«æ°çŸã®ã¯ã©ã¹ãã¡ã€ã«ãããã¯ã¢ãŠããããšãã«çºçããå¯èœæ§ã®ããæ¥åžžçãªãšã©ãŒããªãããã«ããããšãã¯ããã«éèŠã§ãã
ç§ãã¡ã®çµéšãããRepaintBoundariesãå®çŸ©ããããšãæå³ããŠããªãéããããªãŒå šäœã«çºçããããã«èŠãããã¯ã»ã«ã®åæç»ã®ã³ã¹ãã¯ãéšåçãªãŠã£ãžã§ããã¬ã€ã¢ãŠãã®ã³ã¹ããããå®éã®ããã©ãŒãã³ã¹ã®èŠå ãšããŠéåžžã«éèŠã§ãã ç¹ã«4Kã¢ãã¿ãŒã®ç¯å²ã«å ¥ããšãã
ããããããã¯ããã«ããŒãå®éã«ãã®çš®ã®ããšãç解ããè¯ãäŸã§ãã ãµãã³ã³ããã¹ããäœæãããå Žåã¯ããã«ããŒãçã«ããªã£ãŠãããããã«å°éããããã®åªããæ¹æ³ã§ãã
å€ãã®å ŽåãããããŸããããã®å ŽåãBuilderã¯ã¯ã©ãã¿ãŒãè¿œå ããŠããã ãã§ããããããåãå ¥ããŸãã代æ¿æ段ã¯åãªãç°ãªãã¿ã€ãã®ã¯ã©ãã¿ãŒã§ãããå°ãªããšãBuilderã§ã¯ãå€ããå°ãªãããã°ããªãããšãä¿èšŒãããŠããŸãã ãã¥ãŒå šäœãåæ§ç¯ãããå ŽåããŸãã¯ãã«ããŒã䜿çšããŠãã¥ãŒãåæ§ç¯ããããšã¯éããªãå ŽåïŒTextEditingControllerãFocusControllerïŒã¯ã»ãšãã©æå³ããªãããã¹ãŠã®å Žåã«ãããŠããã€ã©ãŒãã¬ãŒããæåã§å転ãããããšã¯åºæ¬çã«DRYã§ã¯ãããŸããã
ããã©ãŒãã³ã¹ã®åé¡ããã°ãã°ããããã«ãããã¯ç¢ºãã«éåžžã«ç¶æ³åºæã§ãã ãã®ã¹ã¿ã€ã«ã奜ããªããããã¯ãããããã£ã®ãããªãã®ã䜿ãã®ã¯çã«ããªã£ãŠãããšæããŸãã ããã¯ä»æ¥å¯èœã§ããããã¬ãŒã ã¯ãŒã¯ããäœåãªãã®ãå¿ èŠãšããªãããã§ãïŒãããŠãããããã£ã瀺ãããã«ãããã¯å®éã«ã¯å€ãã®ã³ãŒããå¿ èŠãšããŸããïŒã
ãããããã ããã³ãã¥ããã£ã«TweenAnimationBuilderãšValueListenableBuilderãæ§ç¯ããããã«äŸé Œããæ§ç¯ããStatefulWidgetãæäŸããªãã®ãšå°ã䌌ãŠããŸãã
ããªããæ±ããŠããããã§ã¯ãããŸãããããã®ã¿ã€ãã®ã¢ãŒããã¯ãã£ã®äž»ãªå©ç¹ã®1ã€ã¯ãç°¡åã«å ±æã§ããå°ããªå°ããªã³ã³ããŒãã³ãã«èªç¶ã«åœ¹ç«ã€ããšã§ãã å°ããªåºç€éšåã1ã€é 眮ãããš...
StatefulWidgetã¯ãPropertyãšæ¯èŒããŠãã³ãŒãã®_lot_ã§ãããéèŠã§ãïŒã»ãšãã©ãã°ã«ãŒã³ãŒãã§ããPropertyãšã¯ç°ãªããŸãïŒã ãšã¯ãããããããã£ãåºãåå©çšããã®ãçã«ããªã£ãŠããå ŽåïŒæ£ç¢ºãªããŒãºã«åºã¥ããŠã¢ããªã±ãŒã·ã§ã³ãããŒã ããšã«ãªãŒããŒã¡ã€ãã®ããŒãžã§ã³ãäœæããã®ã§ã¯ãªãïŒããã®äœ¿çšãæ¯æãã人ã«ããã±ãŒãžãäœæããŠã¢ããããŒãããããšããå§ãããŸãpub
ã 確ãã«ãåãããšãããã¯ã«ãåœãŠã¯ãŸããŸãã ã³ãã¥ããã£ãæ°ã«å
¥ã£ãŠãããã®ã§ããã°ããããã€ããŒãšåãããã«å€ãã®çšéããããŸãã ãã¬ãŒã ã¯ãŒã¯èªäœã«ãã®ãããªãã®ãå
¥ããå¿
èŠãããçç±ã¯æããã§ã¯ãããŸããã
ããã¯æ¬è³ªçã«æ¡åŒµå¯èœã ããã ãšæããŸãã ãããã€ããŒã¯ããã§ã¯ãããŸãããããã¯åãªãããŒã«ã§ãã ããã¯ãStatefulWidgetãšåãããã«ãStatefulComponentsçšã«æ¡åŒµãããããã«äœæããããã®ã§ãã ãããæ¯èŒçäºçŽ°ãªããšã§ãããšããäºå®ã¯ãå¿ ãããããã«å¯ŸããŠä¿æãããã¹ãã§ã¯ãããŸãããïŒ
ããã®ã¹ã¿ã€ã«ã奜ã人ãã«ã€ããŠã®ã¡ã¢ã 3ã€ã®ãªãŒããŒã©ã€ããš15ã30è¡ãç¯çŽã§ããã°ãã»ãšãã©ã®å Žåãèªã¿ããããåäžããŸãã 客芳çã«èšãã°ã€ã¢ã ãŸãã2ã€ã®ã¯ã©ã¹å šäœã®ãšã©ãŒïŒç©ãåŠåããã®ãå¿ãããdepsãæŽæ°ããã®ãå¿ããïŒã客芳çã«æé€ããŸãã
çŽ æŽãããè°è«ãããããšãããããã©ãã«è¡ãã®ãèŠãŠè奮ããŠããŸããç§ã¯ééããªãããã«ãããæ®ããŸã:)
ç³ãèš³ãããŸãããããã®ã¹ã¬ããã¯ãç§ãåãçµãã§ããå¥ã®ãããžã§ã¯ããçµäºãããšãã«èšç»ãããŠãããã©ãã¿ãŒã«æ»ãããšã«å¹»æ» ããŸããã ç§ã欲æ±äžæºãæããŸã
ããã¯ããã¹ãŠã®äž»èŠãªå®£èšåãã¬ãŒã ã¯ãŒã¯ïŒReactãVueãSwift UIãJetpack ComposeïŒããã®åé¡ããã€ãã£ãã«è§£æ±ºããæ¹æ³ãæã£ãŠããããšãèãããšãç¹ã«ã€ã©ã€ã©ããŸãã
ãã®ã¹ã¬ããã§åé¡ãäœåºŠãäœåºŠãæ確ã«èª¬æãããŠããããããã©ãã¿ãŒãµã³ãã«ã¢ããªã®æ§ç¯ã«æéãè²»ããã¹ãã§ã¯ãªããšæããšããç¹ã§ã
ãŸããã¢ããªãäœæããã«ã¯ãœãªã¥ãŒã·ã§ã³ãå¿
èŠãªããããœãªã¥ãŒã·ã§ã³ãæ¢ããŠããå Žåã¯ããã©ãã¿ãŒã§ã¢ããªãäœæããããšã¯ã§ããŸããã ãã®äŒè©±ã®ãã©ãã¿ãŒã®äººã
ã¯å°ãªããšãããªãã¯ã£ããããŠããã®ã§ã圌ãã¯ããã¯ã奜ãã§ã¯ãããŸããã ãããŠãFlutterã«ã¯ãOPã§èª¬æãããŠããåé¡ã«å¯Ÿããå¥ã®è§£æ±ºçããããŸããã ã©ã®ããã«æžãã¹ããã
ããã¯ïŒå°ãªããšãç§ã«ã¯ïŒçå£ã«åãæ¢ããããŠããªããšæããŠããŸãã@ Hixie ãç³ãèš³ãããŸãããWe understand the problem and want to solve it
ãšããæå³ã§çå£ã«åãæ¢ããããŠããªããšããããšã§ãã ä»ã®å®£èšåãã¬ãŒã ã¯ãŒã¯ãšåæ§ã«ãæããã«å®è¡ãããããã§ãã
å¥ã®ããããåãçš®é¡ã®æ¬¡ã®ãããªãã®ã«ã€ããŠïŒ
æžãã®ã¯ç°¡åã§ããïŒ
éçºè ã¯ããã¯ã®æžãæ¹ãåŠã¶å¿ èŠããããŸãããããã¯æ°ããæŠå¿µãªã®ã§ããšãŠãé£ããã§ã
ç§ãæ²ãããããã ãªããããŸã§ã«äœããæ¹åãŸãã¯å€æŽããã®ã§ããïŒ äœããã£ãŠãããã€ã§ããã®è°è«ãããããšãã§ããŸãã ããšãæ°ãã解決çãäžåºŠåŠã¹ã°ã¯ããã«ç°¡åã§æ¥œãããã®ã§ãã£ããšããŠãã ãã®ã¹ããŒãã¡ã³ãã®ããã¯ãå€ãã®ãã®ã«çœ®ãæããããšãã§ããŸãã ç§ã®æ¯ã¯30幎åã«ãã€ã¯ãæ³¢ã«ã€ããŠãã®ãããªæç« ã䜿ãããšãã§ããã§ãããã ããšãã°ãæã®ãããã¯ããããã©ãã¿ãŒããŸãã¯ãããŒããã«çœ®ãæããŠãåãããã«æ©èœããŸãã
æžãã®ã¯ç°¡åã§ããïŒ
åããªã®ã§ãæžãã®ãåããããç°¡åã§ãããªãç°¡åã§ãã
@rrousselGitãis it easier to write?
ïŒããŒã«åçã®è³ªåïŒã§æå³ããããšã¯ãåãã§ããã°çãã¯false
/ undefined
ã¯ãªããšããããšã§ã¯ãªããšæããŸãã
åé¡ãããããšã«åæããããŠããªãã®ã§ãã©ããã£ãŠã©ããã«è¡ãããšãã§ããã®ãããããŸãããå€ãã®äººããããåé¡ã ãšæã£ãŠããã ãã§ãã äŸãã°ïŒ
ããã¯ç¢ºãã«äººã ãè²ãŠãŠãããã®ã§ãã ããã¯ç§ãå èã®çµéšãæã£ãŠãããã®ã§ã¯ãããŸããã Flutterã䜿ã£ãŠèªåã®ã¢ããªãæžããšãã«åé¡ã ãšæãããã®ã§ã¯ãããŸããã ããããããã¯äžéšã®äººã ã«ãšã£ãŠãããæ¬åœã®åé¡ã§ã¯ãªããšããæå³ã§ã¯ãããŸããã
ãããŠãå€ãã®äººãäœåºŠãå€ãã®è°è«ãæäŸããŠããŸãããããªãOPã®ãœãªã¥ãŒã·ã§ã³ãã³ã¢ã«ããå¿
èŠãããã®ãââã
ããšãã°ããµãŒãããŒãã£ãçŸåšãŠã£ãžã§ããã䜿çšããã³äœæããã®ãšåããããç°¡åãã€èªç¶ã«äœ¿çšã§ããããã«ããã«ã¯ãã³ã¢ã«å«ããå¿
èŠããããŸãã ãããŠãä»ã®è€æ°ã®çç±ã ãã³ãã©ã¯ãããã±ãŒãžã«å
¥ããã ãã®ããã§ãã ããããããã¯ã®1ã€ãšããŠãã§ã«ããã±ãŒãžããããŸãã ããã解決ãããã®ã§ããã°ãã¹ã¬ãããéããŠã¿ãŸãããã
@rrousselGitã圌ã®ç³ãåºã«ãããŠãã ããã
ãšã«ãããã©ã€ãã§å°ãæ²ããã®ã§ãä»ã¯è³Œèªã解é€ããŠããŸã-ã©ãã«ãè¡ããªãã®ã§ããã®ã¹ã¬ããããã©ããŒããŠãã ããã ãããããã®ã¹ã¬ãããåé¡ãããããšã«åæããç¶æ ã«ãªããOPã®å¯èœãªè§£æ±ºçã«çŠç¹ãåœãŠãããšãã§ããããã«ãªãããšãé¡ã£ãŠããŸãã @Hixieãããããåæããããã«ã人ã ãçŽé¢ããŠããåé¡ãææ¡ããŠããªãå Žåã解決çãææ¡ããã®ã¯å°ãç¡é§ã«æããã®ã§ãåé¡ã®ãã人ã ã¯
人ã ããããæãã§ããã«ããããããããã©ãã¿ãŒã¯ã³ã¢ã§ãã®åé¡ã解決ããã¹ãã§ã¯ãªããšãã ã¯ã£ãããšèšãããšã«ãã£ãŠããã®ã¹ã¬ãããçµäºããããšã§ããªãã«å¹žéãç¥ã£ãŠããŸãã ãŸãã¯è§£æ±ºçãèŠã€ããããšã«ãã£ãŠã ð
LayoutBuilderã¯ãã»ãšãã©ã®ãã«ããŒã§ããFWIWãšã¯éåžžã«ç°ãªããŠã£ãžã§ããã§ãã ãããŸã§ã«èª¬æããææ¡ã¯ãããããLayoutBuilderã®ãããªåé¡ã«ã¯æ©èœããŸããããŸããã³ã¡ã³ãã®åã«èª¬æããèŠä»¶ã«ã¯ãLayoutBuilderãå«ãŸããŠããŸããã ãã®æ°æ©èœã䜿çšããŠLayoutBuilderãåŠçããå¿ èŠãããå Žåã¯ãç¥ã£ãŠããããšãéèŠã§ãã @TimWhitingã䜿çšããŠãææ¡ã®ããŒã¹ãšãªããµã³ãã«ã¢ããªã«ãäŸãšããŠã¬ã€ã¢ãŠããã«ããŒãå«ãŸããŠããããšã確èªããããšããå§ãããŸãã
@Hixieã¯ãã確ãã«ããã€ãã®ãµã³ãã«ãå¿ èŠã§ãã ç§ã¯äœããæºåããŸãïŒãããããµã³ãã«ãäžå®å šã§ããå¯èœæ§ããããããã³ã³ãã€ã©ã®å€æŽãå¿ èŠã ãšæããŸãïŒã äžè¬çãªèãæ¹ã¯ããã«ããŒããã©ããåãããã«ããŒã®å®è£ æ¹æ³ãæ°ã«ããªãã·ã³ã¿ãã¯ã¹ã·ã¥ã¬ãŒã§ãã
ããã§ããFlutterããŒã ã®èª°ãSwiftUIã詳ãã調ã¹ãŠããªããšããå°è±¡ãåããŠããŸããããã§ãªããã°ãç§ãã¡ã®æžå¿µã¯ç解ãããããšæããŸãã ãã¬ãŒã ã¯ãŒã¯ã®å°æ¥ã«ãšã£ãŠãä»ã®ãã©ãããã©ãŒã ãã移è¡ãã人ã ãã§ããã ãã¹ã ãŒãºã«ä¹ãããšãéèŠã§ãããããä»ã®ãã©ãããã©ãŒã ã«ã€ããŠã®ååãªç解ãšãè³åŠäž¡è«ã®ç¥èãå¿ èŠã§ãã ãããŠãFlutterã®çæã®ããã€ããä¿®æ£ã§ãããã©ããã確èªããŸãã æããã«ãFlutterã¯Reactããå€ãã®åªããã¢ã€ãã¢ãåãå ¥ããŠãããæ°ãããã¬ãŒã ã¯ãŒã¯ã§ãåãããšãã§ããŸãã
@ emanuel-lundman
ããã¯ïŒå°ãªããšãç§ã«ã¯ïŒçå£ã«åãæ¢ããããŠããªããšæããŠããŸãã@ Hixie ãç³ãèš³ãããŸããã
We understand the problem and want to solve it
ãšããæå³ã§çå£ã«åãæ¢ããããŠããªããšããããšã§ãã ä»ã®å®£èšåãã¬ãŒã ã¯ãŒã¯ãšåæ§ã«ãæããã«å®è¡ãããããã§ãã
ç§ã¯åé¡ãç解ããŠããªãããšã«å®å šã«åæããŸãã ã ããç§ã¯ãã®åé¡ã«åãçµã¿ç¶ããç解ããããšããŠããŸãã ãã®ãããåé¡ãã«ãã»ã«åãããã¢ã¢ããªãäœæããããšãææ¡ããŸããã æçµçã«ãã¬ãŒã ã¯ãŒã¯ãæ ¹æ¬çã«å€æŽãããããã¬ãŒã ã¯ãŒã¯ã«å°ããªæ©èœãè¿œå ããããããã±ãŒãžã«ãã£ãŠä¿®æ£ãããã©ããã¯ãå®éã«ã¯åé¡ãäœã§ãããã«ãã£ãŠç°ãªããŸãã
@szotp
ããã§ããFlutterããŒã ã®èª°ãSwiftUIã詳ãã調ã¹ãŠããªããšããå°è±¡ãåããŠããŸããããã§ãªããã°ãç§ãã¡ã®æžå¿µã¯ç解ãããããšæããŸãã
ç§ã¯SwiftUIãç 究ããŸããã Swift UIã³ãŒããæžãããšã¯ãFlutterã³ãŒãããã確ãã«åé·ã§ã¯ãããŸããããèªã¿ãããã®ã³ã¹ãã¯éåžžã«é«ããªããŸãã å€ãã®ãéæ³ãããããŸãïŒã€ãŸããã³ã³ã·ã¥ãŒããŒã³ãŒãã§ã¯æããã§ã¯ãªãæ¹æ³ã§æ©èœããããžãã¯ïŒã äžéšã®äººã奜ãã¹ã¿ã€ã«ã ãšå®å šã«ä¿¡ããããšãã§ããŸãããFlutterã®åŒ·ã¿ã®1ã€ã¯ãéæ³ãã»ãšãã©ãªãããšã§ããããšæããŸãã ããã¯ããªããæã ããå€ãã®ã³ãŒããæžãããšãæå³ããŸãããããã¯ãŸããã®ã³ãŒãã®ãããã°ã_ã¯ããã«_ç°¡åã§ããããšãæå³ããŸãã
ãã¬ãŒã ã¯ãŒã¯ã«ã¯ããããã®ã¹ã¿ã€ã«ã®äœå°ããããšæããŸãã MVCã¹ã¿ã€ã«ãReactã¹ã¿ã€ã«ãéåžžã«ç°¡æœãªéæ³ãéæ³ã®ãªãããããåé·ãª... Flutterã®ã¢ãŒããã¯ãã£ã®å©ç¹ã®1ã€ã¯ã移æ€æ§ã®åŽé¢ããã¬ãŒã ã¯ãŒã¯èªäœããå®å šã«åé¢ãããŠããããããã¹ãŠã®ããŒã«ã掻çšã§ããããšã§ãã -ã¯ãã¹ãã©ãããã©ãŒã ã®ãµããŒããããããªããŒããªã©-ãããããŸã£ããæ°ãããã¬ãŒã ã¯ãŒã¯ãäœæããŸãã ïŒflutter_spritesãªã©ã®ä»ã®Flutterãã¬ãŒã ã¯ãŒã¯ããã§ã«ãããŸããïŒåæ§ã«ããã¬ãŒã ã¯ãŒã¯èªäœã¯éå±€åãããæ¹æ³ã§èšèšãããŠãããããããšãã°ããã¹ãŠã®RenderObjectããžãã¯ãåå©çšã§ããŸãããWidgetsã¬ã€ã€ãŒã®ä»£ããã«ãªããŸãããŠã£ãžã§ãããå€ãããã®ã§ã誰ããããã眮ãæãã代æ¿ãã¬ãŒã ã¯ãŒã¯ãäœæããå¯èœæ§ããããŸãã ãããŠãã¡ãããããã±ãŒãžã³ã°ã·ã¹ãã ãããã®ã§ãæ¢åã®ãã¬ãŒã ã¯ãŒã¯ã³ãŒãã倱ãããšãªãæ©èœãè¿œå ã§ããŸãã
ãšã«ãããããã§ã®ç§ã®äœè«ã®ãã€ã³ãã¯ãããããªãŒã«ãªã¢ããã·ã³ã°ã§ã¯ãªããšããããšã§ãã é·æçã«ã¯ãããªãã幞ãã«ãããœãªã¥ãŒã·ã§ã³ãæ¡çšããããšã«ãªããªãå Žåã§ããããã¯ããªãã奜ããªè£œåã®éšåããå©çã享åãç¶ããããšãã§ããªããšããæå³ã§ã¯ãããŸããã
ãã®åé¡ã«é¢å¿ã®ãã人ã¯ã @ TimWhitingãšæ§åã瀺ãã¢ããªãäœæããããšããå§ãããŸãïŒhttps://github.com/TimWhiting/local_widget_state_approachesïŒã ããã¯ãããã§ã³ã¡ã³ãããŠãããã¹ãŠã®äººã ïŒããã¯ã奜ããªäººãšå«ããªäººãå«ãïŒã®ããŒãºã«å¯Ÿå¿ããæ¹æ³ã§ãã®åé¡ã«å¯ŸåŠããæ¹æ³ã®ææ¡ãäœæããã®ã«çŽæ¥åœ¹ç«ã¡ãŸãã
ã_ãã«ããŒããã©ããåãããã«ããŒã®å®è£ æ¹æ³ãæ°ã«ããªãã·ã³ã¿ãã¯ã¹ã·ã¥ã¬ãŒã_ãããã¡ãŒã¹ãã¯ã©ã¹ã®æ©èœãšããŠéçºè ã«æãŸããçç±ãç解ããã®ã¯ããã»ã©é£ããããšã§ã¯ãããŸããã 代æ¿ã¢ãããŒãã®åé¡ãäœåºŠãæŠèª¬ããŠããŸããã
èŠããã«ããã«ããŒã¯åå©çšæ§ã®åé¡ã解決ããŸãããèªã¿ããããæ§æããã®ã¯å°é£ã§ãã ãåé¡ãã¯ãéåžžã«èªã¿ããããã«ããŒã®ãããªæ©èœãå¿ èŠãªããšã§ãã
3ã€ã®ãã¹ãããããã«ããŒãèªã¿ã«ããããšããŸãã¯ãã«ããŒãäžè¬ã«ã³ãŒãã®åå©çšã®ç®çãå®éã«æãããŠããªãããšã«åºæ¬çã«åæããªãå Žåãã¢ããªã¯ãããããæ確ã«ç€ºãããšã¯ã§ããŸããã ç§ãã¡ã®å€ãã¯å®éã«ã¯ãã¹ããæžããã®ãæ¬åœã«å¥œãã§ãã¢ããªã±ãŒã·ã§ã³å šäœã«ã³ãŒããè€è£œããã®ã¯æ¬åœã«å¥œãã§ã¯ãªãã®ã§ã2ã€ã®éçæ³çãªãªãã·ã§ã³ã®éã«ç«ã¡åŸçããŠãããšèããŠããã«éèŠã§ãã
ç§ã¯ä»é±æ«ãæåéãäœæéãèªåã®æéãéãããŸããããã以åã®Googleã®æéã¯èšããŸã§ããªãããã®åé¡ãæ€èšããèãããã解決çã説æãã解決ããããšããŠããããšãæ£ç¢ºã«åŒãåºããããšããŠããŸãã
ãããããã§ã
äœãåé¡ãªã®ãç解äžè¶³ãšæ··åããªãã§ãã ããã
ç解ã足ããªããŠã倧äžå€«ã§ãããçŸç¶ã¯çµ¶æçã§ãã
è°è«ã®åé ã§ææãããç¹ã«ã€ããŠã¯ããŸã è°è«äžã§ãã
ç§ã®èŠ³ç¹ããã¯ãããŸããŸãªåé¡ã玹ä»ãã詳现ãªã³ã¡ã³ããæžãããã質åã«çãããããã®ã«äœæéãè²»ããããããªæ°ãããŸãããç§ã®ã³ã¡ã³ãã¯åŽäžãããåã質åãå床åºãããŸããã
ããšãã°ãçŸåšã®æ§æã®å¯èªæ§ã®æ¬ åŠãè°è«ã®äžå¿ã«ãããŸãã
ãããè£ä»ããããã«ãèªã¿ãããã®åé¡ãããã€ãåæããŸããã
ãããã®åæã«ã¯ããªãã®æ°ããããŸãðãããŠä»ã®äººã ã¯åæããŠããããã§ã
ããã§ãæè¿ã®åçã«ãããšãèªã¿ãããã®åé¡ã¯ãããŸããïŒ https ïŒ
ããªããææ¡ããŸããïŒ
Widget build(context) {
var result = Text('result:');
var builder1 = (BuildContext context, AsyncSnapshot<int> snapshot) {
return Row(children: [result, Text(snapshot.data)]);
};
result = StreamBuilder(stream: _stream1, builder: builder1);
var builder2 = (BuildContext context, AsyncSnapshot<int> snapshot) {
return Column(children: [result, Text(snapshot.data)]);
};
result = StreamBuilder(stream: _stream2, builder: builder2);
}
ãããèªããªãããšãç¥ã£ãŠãã
ãããã®2ã€ã®ã³ã¡ã³ãããã次ã®ããã«çµè«ä»ããããšãã§ããŸãã
ããã¯ã®å¯äžã®ç®çããã«ããŒã®æ§æãæ¹åããããšã§ããããšãèãããšãããã¯èããŠãã£ããããŸãããã«ããŒã¯åå©çšæ§ã®ããŒã¯ã«ãããŸãããèªã¿ããããæžã蟌ã¿æ§ãå£ã£ãŠããŸãã
ãã®ãããªåºæ¬çãªäºå®ã«åæããªããšãç§ãã¡ã«äœãã§ãããããããŸããã
@Hixieããããšããããã¯ããªãã®èŠç¹ãç解ããã®ã«å€§ãã«åœ¹ç«ã¡ãŸãã ç§ã¯åœŒããã³ãŒãããžãã¯ã§è¡ãéãããããããªãããšã«åæããŸãããããç§ã¯åœŒããæ£ããã£ãããšã¯å°ãªããšãããã€ããããšç¢ºä¿¡ããŠããŸãã
ãããŠãç§ã¯Flutterã®ã¬ã€ã€ãŒãã¢ãŒããã¯ãã£ããšãŠã奜ãã§ãã ãŠã£ãžã§ããã䜿ãç¶ãããã§ãã ãããã£ãŠãããããçãã¯ãDartïŒFlutterã®æ¡åŒµæ§ãæ¹åããããšã§ããããã¯ç§ã«ãšã£ãŠã¯æ¬¡ã®ããã«ãªããŸãã
ã³ãŒãçæãããã·ãŒã ã¬ã¹ã«ããŸã-Dartã§SwiftUIããžãã¯ãå®è£ ããããšã¯å¯èœãããããŸããããå¿ èŠãªéåžžã®ã»ããã¢ããã¯å€§ããããŠé ãããŸãã
ã³ãŒãçæã®äœ¿çšãããã±ãŒãžã®ã€ã³ããŒããšããã€ãã®æ³šéã®å¹³ææã¡ã®ããã«åçŽã§ããå Žåãè°è«ãããåé¡ãæ±ããŠãã人ã ã¯ãããè¡ãã ãã§æå¥ãèšãã®ããããŸãã æ®ãã¯ãå€ãè¯ãStatefulWidgetsãçŽæ¥äœ¿çšãç¶ããŸãã
ç·šéïŒ flutter generate
ã¯è¯ãæ¹åãžã®äžæ©ã ã£ããšæããŸãããããåé€ãããããšãæ®å¿µã«æããŸãã
ããã¯ã次ã®Flutter DeveloperSurveyã§å°ããéåžžã«èå³æ·±ã質åã«ãªããšæããŸãã
ããã¯è¯ãã¹ã¿ãŒãã«ãªãã§ãããã ãã®åé¡ãããŸããŸãªéšå/質åã«åããŠããããFlutteréçºè ã解決ãããæ¬åœã®åé¡ã§ãããã©ããã確èªããŠãã ããã
ãããæ確ã«ãªããšããã®äŒè©±ã¯ããæµæ¢ã§è±ãã«ãªããŸã
ç§ã®èŠ³ç¹ããã¯ãããŸããŸãªåé¡ã玹ä»ãã詳现ãªã³ã¡ã³ããæžãããã質åã«çãããããã®ã«äœæéãè²»ããããããªæ°ãããŸãããç§ã®ã³ã¡ã³ãã¯åŽäžãããåã質åãå床åºãããŸããã
åã質åãããŠããã®ã¯ãçããããããªãããã§ãã
ããšãã°ã以åã®ã³ã¡ã³ãïŒhttps://github.com/flutter/flutter/issues/51752#issuecomment-670959424ïŒã«æ»ããŸãã
è°è«ãããŠããåé¡ã¯æ¬¡ã®ãšããã§ãã
Widget build(context) { return ValueListenableBuilder<String>( valueListenable: someValueListenable, builder: (context, value, _) { return StreamBuilder<int>( stream: someStream, builder: (context, value2) { return TweenAnimationBuilder<double>( tween: Tween(...), builder: (context, value3) { return Text('$value $value2 $value3'); }, ); }, ); }, ); }
ãã®ã³ãŒãã¯èªã¿åãå¯èœã§ã¯ãããŸããã
ç§ã¯ããã«ã€ããŠèªããªããã®ãæ¬åœã«ããããŸããã ããã¯äœãèµ·ãã£ãŠããã®ããæ£ç¢ºã«èª¬æããŠããŸãã 4ã€ã®ãŠã£ãžã§ããããããŸãã3ã€ã®ãŠã£ãžã§ããã«ã¯ãã«ããŒã¡ãœãããããã1ã€ã«ã¯æååããããŸãã å人çã«ã¯åãçç¥ããŸããããå€æ°ãäœãªã®ãããããªãã®ã§èªã¿ã¥ãããªããšæããŸããã倧ããªåé¡ã§ã¯ãããŸããã
ãªããããèªããªãã®ã§ããïŒ
æ確ã«ããããã«ãæããã«ããªãã¯ãããèªããªãããšã«æ°ã¥ããŸããç§ã¯ããªããééã£ãŠãããšèšã£ãŠããã®ã§ã¯ãããŸããã çç±ãããããŸããã
æ§æã次ã®ããã«å€æŽããæ°ããããŒã¯ãŒããå°å ¥ããããšã§ãèªã¿ãããã®åé¡ãä¿®æ£ã§ããŸãã
Widget build(context) { final value = keyword ValueListenableBuilder(valueListenable: someValueListenable); final value2 = keyword StreamBuilder(stream: someStream); final value3 = keyword TweenAnimationBuilder(tween: Tween(...)); return Text('$value $value2 $value3'); }
ãã®ã³ãŒãã¯éåžžã«èªã¿ããããããã¯ãšã¯ç¡é¢ä¿ã§ãããå¶éã®åœ±é¿ãåããŸããã
確ãã«åé·ã§ã¯ãããŸããã å°ãªããšãç§ã«ãšã£ãŠã¯ããã以äžèªã¿ããããã©ããã¯ããããŸããã ããå€ãã®æŠå¿µããããŸãïŒçŸåšããŠã£ãžã§ãããšãã®ãããŒã¯ãŒããæ©èœã®äž¡æ¹ããããŸãïŒã ããå€ãã®æŠå¿µã¯ããå€ãã®èªç¥çè² è·ãæå³ããŸãã ïŒãããã®ãªããžã§ã¯ããã©ãã ãç¬ç«ããŠãããã«ãã£ãŠã¯ãå¹çãäœäžããå¯èœæ§ããããŸããããšãã°ãã¢ãã¡ãŒã·ã§ã³ãåžžã«ãªãã¹ã³å¯èœãªå€ãšã¹ããªãŒã ãããé »ç¹ã«å€æŽãããå Žåãéåžžã¯ããªã¬ãŒãããªãã«ãããããããValueListenableBuilderãšStreamBuilderãåæ§ç¯ããŠããŸãã ;ãŸããåæåããžãã¯ãå ¥åããŠããã«ãããšã«ã¹ãããããå¿ èŠããããŸããïŒ
åé·æ§ã¯åé¡ã§ã¯ãªããšãã£ããã£ãŠããã®ã§ãç°¡æœã§ããããšãèªã¿ãããçç±ã§ã¯ãªããšæããŸãïŒãã ããåé¡ã®ã¿ã€ãã«ãšã«ãåé·ãããããšå ¥åãããããããã«ã€ããŠãæ··ä¹±ããŠããŸããåé¡ã®å ã®èª¬æïŒã ã€ã³ãã³ããæžãããããšãã£ããããŸããããã€ã³ãã³ããªãã§ãã«ããŒã䜿çšããããŒãžã§ã³ãå€èªã§ããªããšèª¬æããã®ã§ãããããåé¡ã¯ãªãªãžãã«ã®ã€ã³ãã³ãã§ã¯ãããŸããã
ãã«ããŒã¯åå©çšæ§ã®ããŒã¯ã§ãããå¥ã®æ§æãå¿ èŠã ãšèšããŸãããææ¡ããææ¡ã¯ãã«ããŒã®ãããªãã®ã§ã¯ãªãããïŒãŠã£ãžã§ãããèŠçŽ ãäœæããŸããïŒãç¹ã«ãã«ããŒã®åŽé¢ã§ã¯ãããŸãããæ¢ããŠããã
ããªãã¯ããªãã奜ããªè§£æ±ºçïŒããã¯ïŒãæã£ãŠããŸããããã¯ç§ãç¥ãéãããŸããããŸãããããããªãã¯äººã ãããã¯ã䜿ãããã«ãã¬ãŒã ã¯ãŒã¯ã§äœããå€ãããã§ããïŒ ç§ãç解ããŠããŸããããªããªãã人ã ãããã¯ãããã±ãŒãžãšããŠäœ¿çšããã®ã«ååãªã»ã©å¥œãã§ã¯ãªãå Žåãããã¯ãããããã¬ãŒã ã¯ãŒã¯ã«ãšã£ãŠãè¯ã解決çã§ã¯ãªãããã§ãïŒäžè¬çã«ãç§ãã¡ã¯ããã±ãŒãžãããã«ã¯æ©èœã䜿çšããæ¹åã«é²ãã§ããŸãFlutterããŒã ã¯ããã®äŸ¡å€ã®ããã«äœæããŸãïŒã
ã³ãŒããããç°¡åã«åå©çšããããšããèŠæãããããšãç解ããŠããŸãã ãããäœãæå³ããã®ãããããŸããã
以äžã¯ãèªã¿ãããã«ãããŠäžèšã®2ã€ã®ããŒãžã§ã³ãšã©ã®ããã«æ¯èŒãããŸããïŒ
Widget build(context) {
return
ValueListenableBuilder(valueListenable: someValueListenable, builder: (context, value, _) =>
StreamBuilder(stream: someStream, builder: (context, value2) =>
TweenAnimationBuilder(tween: Tween(...), builder: (context, value3) =>
Text('$value $value2 $value3'),
)));
}
@szotpçŸåšã®codegenãœãªã¥ãŒã·ã§ã³ã«ããŸãã«ãå€ãã®æ©æŠãããå Žåã¯ãããã§æ¹åãæ±ãããã°ãæåºããããšãèºèºããªãã§ãã ããã
@jamesblasco人ã ã解決ãããæ¬åœã®åé¡ãããã«ããããšã«çãã®äœå°ã¯ãªããšæããŸãã ç§ã«ãšã£ãŠã®åé¡ã¯ããŸãã«ãã®åé¡ãäœã§ããããšããããšã§ããããããã°ã解決çãèšèšããããšãã§ããŸãã
ããã¯ã®æ¬ é¥ãã³ãŒãã«å«ããããšããæžå¿µã«çããããšã¯ã§ããŸããããä»ã¯ãããéèŠãã¹ãã§ã¯ãªããšæããŸãã
ãŸããåé¡ãäœã§ãããã«ã€ããŠåæããå¿ èŠããããŸãã ããããªããšãä»ã®ãããã¯ã«ã€ããŠã©ã®ããã«åæã§ãããããããŸããã
ç§ã¯ããã«ã€ããŠèªããªããã®ãæ¬åœã«ããããŸããã ããã¯äœãèµ·ãã£ãŠããã®ããæ£ç¢ºã«èª¬æããŠããŸãã 4ã€ã®ãŠã£ãžã§ããããããŸãã3ã€ã®ãŠã£ãžã§ããã«ã¯ãã«ããŒã¡ãœãããããã1ã€ã«ã¯æååããããŸãã å人çã«ã¯åãçç¥ããŸããããå€æ°ãäœãªã®ãããããªãã®ã§èªã¿ã¥ãããªããšæããŸããã倧ããªåé¡ã§ã¯ãããŸããã
ããã§ã®åé¡ã®å€§éšåã¯ãã³ãŒãã£ã³ã°ã®æ¹æ³ãã»ãšãã©ã®äººã®ã³ãŒãã£ã³ã°æ¹æ³ãšå€§å¹ ã«ç°ãªãããšã ãšæããŸãã
ããšãã°ãFlutterãšããªããäž¡æ¹ãäžããã¢ããªã®äŸïŒ
ãããã®2ã€ã®ãã€ã³ãã ãã§ããããã³ãã¥ããã£ã®1ïŒ ä»¥äžãå ãããšããããç§ã¯é©ããŸãã
ãã®ãããèªã¿åãå¯èœãšè©äŸ¡ãããã®ã¯ãã»ãšãã©ã®äººãèªã¿åãå¯èœãšèãããã®ãšã¯å€§ããç°ãªãå¯èœæ§ããããŸãã
ç§ã¯ããã«ã€ããŠèªããªããã®ãæ¬åœã«ããããŸããã ããã¯äœãèµ·ãã£ãŠããã®ããæ£ç¢ºã«èª¬æããŠããŸãã 4ã€ã®ãŠã£ãžã§ããããããŸãã3ã€ã®ãŠã£ãžã§ããã«ã¯ãã«ããŒã¡ãœãããããã1ã€ã«ã¯æååããããŸãã å人çã«ã¯åãçç¥ããŸããããå€æ°ãäœãªã®ãããããªãã®ã§èªã¿ã¥ãããªããšæããŸããã倧ããªåé¡ã§ã¯ãããŸããã
ãªããããèªããªãã®ã§ããïŒ
ç§ã®æšå¥šã¯ãç¹å®ã®ãã®ãæ€çŽ¢ãããšãã«ããªãã®ç®ãã©ããèŠãŠãããããããŠããã«å°éããããã«äœã¹ããããããããåæããããšã§ãã
å®éšããŠã¿ãŸãããïŒ
2ã€ã®ãŠã£ãžã§ããããªãŒãæäŸããŸãã 1ã€ã¯ç·åœ¢æ§æã䜿çšãããã1ã€ã¯ãã¹ããããæ§æã䜿çšããŸãã
ãŸãããã®ã¹ããããã§æ¢ãå¿
èŠã®ããå
·äœçãªäºé
ã«ã€ããŠã説æããŸãã
ç·åœ¢æ§æãŸãã¯ãã¹ããããæ§æã䜿çšããããšã«å¯ŸããçããèŠã€ããã®ã¯ç°¡åã§ããïŒ
質åïŒ
bar
ãäœæããŸããïŒãã«ããŒã®äœ¿çšïŒ
ãŠã£ãžã§ãããã«ãïŒã³ã³ããã¹ãïŒ{ ValueListenableBuilderãè¿ããŸãïŒïŒ valueListenableïŒsomeValueListenableã ãã«ããŒïŒïŒcontextãfooã_ïŒ{ StreamBuilderãè¿ã ïŒïŒ ã¹ããªãŒã ïŒsomeStreamã ãã«ããŒ:(ã³ã³ããã¹ããbazïŒ{ TweenAnimationBuilderãè¿ã ïŒïŒ ãã¥ã€ãŒã³ïŒãã¥ã€ãŒã³ïŒ...ïŒã ãã«ããŒ:(ã³ã³ããã¹ããããŒïŒ{ ContainerïŒïŒ;ãè¿ããŸãã }ã ïŒ; }ã ïŒ; }ã ïŒ; }
ç·åœ¢æ§æã®äœ¿çšïŒ
ãŠã£ãžã§ãããã«ãïŒã³ã³ããã¹ãïŒ{
æçµçãªfoo =ããŒã¯ãŒãValueListenableBuilderïŒvalueListenableïŒsomeValueListenableïŒ;
æçµããŒ=ããŒã¯ãŒãStreamBuilderïŒstreamïŒsomeStreamïŒ;
æçµçãªbaz =ããŒã¯ãŒãTweenAnimationBuilderïŒtweenïŒTweenïŒ...ïŒïŒ;
ImageïŒïŒ;ãè¿ã
}
ç§ã®å Žåããã¹ããããã³ãŒãã調ã¹ãŠçããèŠã€ããã®ã«èŠåŽããŠããŸãã
äžæ¹ãç·åœ¢ããªãŒã§çããèŠã€ããã®ã¯ç¬æã§ã
ã€ã³ãã³ããæžãããããšãã£ããããŸããããã€ã³ãã³ããªãã§ãã«ããŒã䜿çšããããŒãžã§ã³ãå€èªã§ããªããšèª¬æããã®ã§ããããããåé¡ã¯ãªãªãžãã«ã®ã€ã³ãã³ãã§ã¯ãããŸããã
StreamBuilderãè€æ°ã®å€æ°ã«åå²ããããšã¯æ·±å»ãªææ¡ã§ãããïŒ
ç§ã®ç解ã§ã¯ãããã¯è°è«ãããããã®ç®èãªææ¡ã§ããã ãããããªãã£ãïŒ ãã®ãã¿ãŒã³ã¯ã倧ããªãŠã£ãžã§ããã§ãã£ãŠããããèªã¿ãããã³ãŒãã«ã€ãªãããšæ¬åœã«æããŸããïŒ
äŸãæ©èœããªããšããäºå®ãç¡èŠããŠããªããããèªããªãã®ãã説æããããã«ãããå解ããŠãããŸããŸããã ããã¯äŸ¡å€ããããŸããïŒ
`` `ããŒã
ãŠã£ãžã§ãããã«ãïŒã³ã³ããã¹ãïŒ{
æ»ã
ValueListenableBuilderïŒvalueListenableïŒsomeValueListenableãbuilderïŒïŒcontextãvalueã_ïŒ=>
StreamBuilderïŒstreamïŒsomeStreamãbuilderïŒïŒcontextãvalue2ïŒ=>
TweenAnimationBuilderïŒtweenïŒTweenïŒ...ïŒããã«ããŒïŒïŒcontextãvalue3ïŒ=>
TextïŒ '$ value $ value2 $ value3'ïŒã
ïŒïŒïŒ;
}
ããã¯è¯ãèŠããŸãã
ããããããã¯äººã
ãdartfmtã䜿çšããªãããšãåæãšããŠããŸã
dartfmtã䜿çšãããšã次ã®ããšãã§ããŸãã
Widget build(context) {
return ValueListenableBuilder(
valueListenable: someValueListenable,
builder: (context, value, _) => StreamBuilder(
stream: someStream,
builder: (context, value2) => TweenAnimationBuilder(
tween: Tween(),
builder: (context, value3) => Text('$value $value2 $value3'),
)));
}
ããã¯å ã®ã³ãŒããšã»ãšãã©å€ãããŸããã
ãã«ããŒã¯åå©çšæ§ã®ããŒã¯ã§ãããå¥ã®æ§æãå¿ èŠã ãšèšããŸãããææ¡ããææ¡ã¯ãã«ããŒã®ãããªãã®ã§ã¯ãªãããïŒãŠã£ãžã§ãããèŠçŽ ãäœæããŸããïŒãç¹ã«ãã«ããŒã®åŽé¢ã§ã¯ãããŸãããæ¢ããŠããã
ãããå®è£
ã®è©³çŽ°ã§ãã
èŠçŽ ããããã©ããã«ç¹å¥ãªçç±ã¯ãããŸããã
å®éãèŠçŽ ããããšé¢çœããããããŸãããããããã°ã LayoutBuilder
ãšãå Žåã«ãã£ãŠã¯GestureDetector
å«ããããšãã§ããŸãã
åªå 床ã¯äœããšæããŸãã ããããReactã³ãã¥ããã£ã§ã¯ãããŸããŸãªããã¯ã©ã€ãã©ãªã®äžã§ã次ã®ããšã確èªããŸããã
ïŒãããã®ãªããžã§ã¯ããã©ãã ãç¬ç«ããŠãããã«ãã£ãŠã¯ãå¹çãäœäžããå¯èœæ§ããããŸããããšãã°ãã¢ãã¡ãŒã·ã§ã³ãåžžã«ãªãã¹ã³å¯èœãªå€ãšã¹ããªãŒã ãããé »ç¹ã«å€æŽãããå Žåãéåžžã¯ããªã¬ãŒãããªãã«ãããããããValueListenableBuilderãšStreamBuilderãåæ§ç¯ããŠããŸãã ;ãŸããåæåããžãã¯ãå ¥åããŠããã«ãããšã«ã¹ãããããå¿ èŠããããŸããïŒ
ããã¯ããœãªã¥ãŒã·ã§ã³ãã©ã®ããã«è§£æ±ºããããã«ãã£ãŠç°ãªããŸãã
èšèªã®ä¿®æ£ãè¡ãå Žåããã®åé¡ã¯ãŸã£ããåé¡ã«ãªããŸããã
ç§ãã¡ã¯ãããäœãããšãã§ããŸãïŒ
Widget build(context) {
final value = keyword ValueListenableBuilder(valueListenable: someValueListenable);
final value2 = keyword StreamBuilder(stream: someStream);
final value3 = keyword TweenAnimationBuilder(tween: Tween(...));
return Text('$value $value2 $value3');
}
ãã³ã³ãã€ã«ãããŠïŒ
Widget build(context) {
return ValueListenableBuilder<String>(
valueListenable: someValueListenable,
builder: (context, value, _) {
return StreamBuilder<int>(
stream: someStream,
builder: (context, value2) {
return TweenAnimationBuilder<double>(
tween: Tween(...),
builder: (context, value3) {
return Text('$value $value2 $value3');
},
);
},
);
},
);
}
ããã¯ã䜿çšããŠããå Žåãflutter_hooksã«ã¯HookBuilder
ãŠã£ãžã§ãããä»å±ããŠãããããå¿
èŠãªãšãã«åå²ããããšãã§ããŸãã
åæ§ã«ãç¹ã«ããã§äœæããäŸã§ã¯ããããæ¬åœã«åé¡ã§ãããã©ãããå€æããããã®é©åãªãã³ãããŒã¯ãå¿
èŠã«ãªããŸãã
ããã¯ã䜿çšããŠã1ã€ã®èŠçŽ ã®ã¿ãåæ§ç¯ããŠããŸãã
Builderã䜿çšãããšãåæ§ç¯ã¯è€æ°ã®èŠçŽ ã«åå²ãããŸãã ããã¯ãããšãå°ãããŠããããããã®ãªãŒããŒããããè¿œå ããŸãã
ãã¹ãŠã®ããã¯ãåè©äŸ¡ããæ¹ãéãããšã¯äžå¯èœã§ã¯ãããŸããã ããããããã¯ãèšèšãããšãã«åœŒããæãã€ããReactããŒã ã®çµè«ã ã£ãããã§ãã
ãã ããããã¯Flutterã«ã¯åœãŠã¯ãŸããªãå ŽåããããŸãã
ãªããããèªããªãã®ã§ããïŒ
ãã¹ãã£ã³ã°ãããããããã¹ãã£ã³ã°ã䜿çšãããšãç¡èŠã§ããéšåãšãäœãèµ·ãã£ãŠããã®ããç解ããããã«äžå¯æ¬ ãªéšåããã°ããã¹ãã£ã³ããŠç¥ãããšãé£ãããªããŸãã ã³ãŒãã¯æ¬è³ªçã«ãã·ãŒã±ã³ã·ã£ã«ãã§ããããã¹ãã¯ãããé ããŸãã ãã¹ãã¯ãŸãããããæäœããã®ãé£ããããŸã-2ã€ã®ãã®ã䞊ã¹æ¿ããããšæ³åããŠãã ãã-ãŸãã¯2ã€ã®éã«æ°ãããã®ãæ³šå ¥ããŸã-çã®ã·ãŒã±ã³ã·ã£ã«ã³ãŒãã§ã¯ç°¡åã§ããããã¹ããæäœããå¿ èŠãããå Žåã¯å°é£ã§ãã
ããã¯async / awaitsugarãšçã®FutureAPIã§ã®äœæ¥ã«éåžžã«äŒŒãŠããããã®äžã«ç¶ç¶ããŒã¹ã®æŠå¿µããããŸãïŒãããŠè³æãšå察ã®è°è«ãéåžžã«äŒŒãŠããŸãïŒ-ã¯ãFuture APIã¯çŽæ¥äœ¿çšã§ããäœãé ããŸããããèªã¿ããããšä¿å®æ§ç¢ºãã«è¯ããããŸãã-async / awaitãåè ã§ãã
ç§ã®æšå¥šã¯ãç¹å®ã®ãã®ãæ€çŽ¢ãããšãã«ããªãã®ç®ãã©ããèŠãŠãããããããŠããã«å°éããããã«äœã¹ããããããããåæããããšã§ãã
ç§ã¯25幎éã10以äžã®ç°ãªãèšèªã§ããã°ã©ãã³ã°ãè¡ã£ãŠããŸããããããã¯ã³ãŒããèªã¿ããããããã®ãè©äŸ¡ããããã®ããæªãæ¹æ³ã§ãã ãœãŒã¹ã³ãŒãã®èªã¿ãããã¯æ³šæãå¿ èŠã§ããããç§ã®ç®ãã©ããèŠãŠããããã䜿çšããã³ãŒãã®è¡æ°ã§ã¯ãªããããã°ã©ãã³ã°ã®æŠå¿µãšããžãã¯ãã©ãã ãããŸãè¡šçŸããããéèŠã§ãã
ããããçããã¯èªã¿ãããã«éç¹ã眮ããããŠãä¿å®æ§ã«éç¹ã眮ããŠããªãããã§ãã
ã³ãŒãã®__intent__ããããã«ãããåãå Žæã«ããŸããŸãªæžå¿µäºé ãé ãããŠãããšãä¿å®ãé£ãããªããããäŸã¯èªã¿ã«ãããªããŸãã
final value = keyword ValueListenableBuilder(valueListenable: someValueListenable);
䟡å€ã¯äœã§ãããããŸããïŒ ãŠã£ãžã§ããïŒ æååå€æ°ïŒ ç§ã¯ãããå
éšã§äœ¿çšãããŠããããšãæå³ããŸãreturn Text('$value $value2 $value3');
åºæ¬çã«å¿ èŠãªã®ã¯ããŠã£ãžã§ããBã®buildã¡ãœããã§å€æ°Aãåç §ããããšã«ãããAã®å€ãå€æŽããããã³ã«Bãåæ§ç¯ããå¿ èŠããããšããããšã§ãã ããã¯æåéãmobxãè¡ãããšã§ãããé©åãªéã®éæ³/ãã€ã©ãŒãã¬ãŒãã§æ£ç¢ºã«è¡ããŸãã
final value2 = keyword StreamBuilder(stream: someStream);
ããã¯äœãè¿ãå¿ èŠããããŸããïŒ ãŠã£ãžã§ããïŒ ã¹ããªãŒã ïŒ æååå€ïŒ
ç¹°ãè¿ããŸãããæååå€ã®ããã«èŠããŸãã ãããã£ãŠãbuildã¡ãœããã§ã¹ããªãŒã ãåçŽã«åç §ããã¹ããªãŒã ãå€ãçºè¡ãããã³ã«ãã®ãŠã£ãžã§ãããåæ§ç¯ããçºè¡ãããå€ã«ã¢ã¯ã»ã¹ã§ããããã«ãããŠã£ãžã§ãããäœæ/æŽæ°ããããã³ã«ã¹ããªãŒã ãäœæ/æŽæ°/ç Žæ£ã§ããããã«ããå¿ èŠããããŸãã /ç Žå£ãããŸããïŒ 1è¡ã®ã³ãŒãã§ïŒ ãã«ãã¡ãœããã®å éšïŒ
ã¯ããmobxã䜿çšãããšããã«ãã¡ãœããããããèªã¿ããããäŸãšãŸã£ããåãããã«èŠããããšãã§ããŸãïŒãªãã¶ãŒããã«ãåç §ããå Žåãé€ãïŒã ããã¯ã®å Žåãšåãããã«ããã¹ãŠã®äœæ¥ãå®è¡ããå®éã®ã³ãŒããäœæããå¿ èŠããããŸãã å®éã®ã³ãŒãã¯çŽ10è¡ã§ãã©ã®ãŠã£ãžã§ããã§ãåå©çšã§ããŸãã
final value3 = keyword TweenAnimationBuilder(tween: Tween(...));
æååãè¿ããTweenAnimationBuilderããšããã¯ã©ã¹ïŒïŒ ãªããããã²ã©ãèããªã®ããç§ã¯è¿ã¥ããŠããŸããã
以äžã®éã§ã€ã³ãã³ã/èªã¿ãããã«éãã¯ãããŸããã
Future<double> future;
AsyncSnapshot<double> value = keyword FutureBuilder<double>(future: future);
ãšïŒ
Future<double> future;
double value = await future;
ã©ã¡ãããŸã£ããåãããšãè¡ããŸãããªããžã§ã¯ãããªãã¹ã³ãããã®å€ãã¢ã³ã©ããããŸãã
ç§ã¯ããã«ã€ããŠèªããªããã®ãæ¬åœã«ããããŸããã ããã¯äœãèµ·ãã£ãŠããã®ããæ£ç¢ºã«èª¬æããŠããŸãã 4ã€ã®ãŠã£ãžã§ããããããŸãã3ã€ã®ãŠã£ãžã§ããã«ã¯ãã«ããŒã¡ãœãããããã1ã€ã«ã¯æååããããŸãã å人çã«ã¯åãçç¥ããŸããããå€æ°ãäœãªã®ãããããªãã®ã§èªã¿ã¥ãããªããšæããŸããã倧ããªåé¡ã§ã¯ãããŸããã
åãè°è«ãPromise / Futureãã§ãŒã³ã«ãåœãŠã¯ãŸããŸãã
foo().then(x =>
bar(x).then(y =>
baz(y).then(z =>
qux(z)
)
)
)
vs
let x = await foo();
let y = await bar(x);
let z = await baz(y);
await qux(z);
æåã®æžãæ¹ã§ã¯ãPromiseãå éšã§äœæãããŠããããšãããã³ãã§ãŒã³ãã©ã®ããã«æ£ç¢ºã«åœ¢æãããŠããããæ確ã«ãªã£ãŠãããšèšããŸãã ããªããããã賌èªããŠããã®ãããããšãPromisesãæ§æã«å€ãããšããç¹ã§Buildersãšã¯æ ¹æ¬çã«ç°ãªããšèããŠããã®ã ãããã
æååãè¿ããTweenAnimationBuilderããšããã¯ã©ã¹ïŒïŒ ãªããããã²ã©ãèããªã®ããç§ã¯è¿ã¥ããŠããŸããã
Promises / Futuresã«ã€ããŠãåãè°è«ãããããšãã§ãã await
ã¯Promiseãè¿ããšããäºå®ãèŠãé ããŠãããšèšãããšãã§ããŸãã
æ§æãä»ããŠç©äºããã¢ã³ã©ããããããšããèãã¯ãã»ãšãã©æ°ãããã®ã§ã¯ãªãããšã«æ³šæããå¿
èŠããããŸãã ã¯ããäž»æµã®èšèªã§ã¯async / awaitãä»ããŠæäŸãããŠããŸããããããšãã°ãFïŒã«ã¯ãäžéšã®ããŒãã³ã¢FPèšèªã®do
è¡šèšã«äŒŒãèšç®åŒããããŸãã ããã§ã¯ãããã¯ã¯ããã«åŒ·åã§ãããç¹å®ã®æ³åãæºããä»»æã®ã©ãããŒã§åäœããããã«äžè¬åãããŠããŸãã ã¢ãããããŒãã«è¿œå ããããšãææ¡ããŠããããã§ã¯ãããŸããããéåæåŒã³åºãã«å¿
ããã察å¿ããªããã®ããã¢ã³ã©ãããããããã®ã¿ã€ãã»ãŒããªæ§æã®åäŸãããããšã¯ééããªããããšæããŸãã
äžæ©åŸéããŠãããã®å€ãã®äººã
ãïŒç§èªèº«ãå«ããŠïŒèŠåŽããŠããããšã®1ã€ã¯ãèªã¿ãããã«ã€ããŠã®ãã®è³ªåã ãšæããŸãã @rrousselGitãè¿°ã¹ãããã«ãçŸåšã®Builder
ããŒã¹ã®ã¢ãããŒãã§ã¯ããã®å¯èªæ§ã®åé¡ã®ã¹ã¬ããå
šäœã«å€ãã®äŸããããŸãã ç§ãã¡ã®å€ãã«ãšã£ãŠãããã¯èªæã®ããã§ãã
Widget build(context) {
return ValueListenableBuilder<String>(
valueListenable: someValueListenable,
builder: (context, value, _) {
return StreamBuilder<int>(
stream: someStream,
builder: (context, value2) {
return TweenAnimationBuilder<double>(
tween: Tween(...),
builder: (context, value3) {
return Text('$value $value2 $value3');
},
);
},
);
},
);
}
ãããããå€§å¹ ã«èªã¿ã«ãããªããŸãã
Widget build(context) {
final value = keyword ValueListenableBuilder(valueListenable: someValueListenable);
final value2 = keyword StreamBuilder(stream: someStream);
final value3 = keyword TweenAnimationBuilder(tween: Tween(...));
return Text('$value $value2 $value3');
}
ãããã @ Hixieãš@Rudikszã¯ã2çªç®ã®æ¹ãæåã®æ¹ããèªã¿ããããšããèãã«çŽåŸããŠããªãïŒãŸãã¯ç©æ¥µçã«å察ããŠããïŒãããæããã«èªæã§ã¯ãããŸããã
ãããã£ãŠã2çªç®ã®ã³ãŒããããã¯ãæåã®ã³ãŒããããã¯ãããèªã¿ãããçç±ã«ã€ããŠã®ç§ã®å èš³ã¯æ¬¡ã®ãšããã§ãïŒå°ãã§ã䟡å€ããããŸãïŒã
ç§ã®çµéšã§ã¯ãã€ã³ãã³ãã¯éåžžãéåææ§ãåå²ããŸãã¯ã³ãŒã«ããã¯ãšåçã§ããããããã¯ãã¹ãŠãã€ã³ãã³ããããŠããªãç·åœ¢ã³ãŒããããå€ãã®èªç¥çè² è·ãå¿
èŠãšããŸãã æåã®ã³ãŒããããã¯ã«ã¯ããã€ãã®ã€ã³ãã³ãã®å±€ãããããã®ãããããã§äœãèµ·ãã£ãŠããã®ãããããŠæçµçã«äœãã¬ã³ããªã³ã°ãããŠããã®ãïŒåäžã®Text
ïŒãåŠçããã®ã«åãã«è¶³ããªãæéãããããŸãã ãã¶ããä»ã®äººã
ã¯åœŒãã®å¿ã®äžã§ãã®ããŒã¿ãéããŠåãã®ãäžæã§ãã
2çªç®ã®ã³ãŒããããã¯ã«ã¯ãåé¡ã軜æžããã€ã³ãã³ãã¯ãããŸããã
æåã®ã³ãŒããããã¯ã«ã¯ã3ã€ã®return
ã¹ããŒãã¡ã³ãã3ã€ã®ãã«ããŒã¹ããŒãã¡ã³ãã3ã€ã®ã©ã ãããããŒã3ã€ã®ã³ã³ããã¹ãããããŠæåŸã«3ã€ã®å€ããããŸãã æçµçã«ç§ãã¡ãæ°ã«ããã®ã¯ãããã3ã€ã®äŸ¡å€èŠ³ã§ããæ®ãã¯ãç§ãã¡ãããã«å°ãããã®å®åæã§ãã ç§ã¯å®éãããããã®ã³ãŒããããã¯ã®æãé£ããéšåã§ãããšæããŠããŸãã éåžžã«å€ãã®ããšãèµ·ãã£ãŠãããç§ãå®éã«æ°ã«ãããŠããéšåïŒãã«ããŒããè¿ãããå€ïŒã¯éåžžã«å°ããã®ã§ãå®éã«å¿
èŠãªéšåã«éäžããã®ã§ã¯ãªãã粟ç¥çãªãšãã«ã®ãŒã®ã»ãšãã©ããã€ã©ãŒãã¬ãŒãã«è²»ãããŠããŸãïŒç¹°ãè¿ããŸãããå€ïŒã
2çªç®ã®ã³ãŒããããã¯ã§ã¯ããã€ã©ãŒãã¬ãŒããå€§å¹ ã«åæžãããŠãããããé¢å¿ã®ããéšåã«çŠç¹ãåœãŠãããšãã§ããŸãããããå€ã§ãã
build
ã¡ãœããã®æãéèŠãªéšåãé衚瀺ã«ããŸãããã®build
ã¡ãœããã®ãã¹ãŠã®éšåãéèŠã§ããããšãèªèããŠããŸããããã®ã¹ã¿ã€ã«ã®å®£èšåUIã³ãŒããèªãã§ãããšãã«ãç§ãéåžžæ¢ããŠããã®ã¯ã衚瀺ããããã®ãã¹ãŠã§ãããŠãŒã¶ãŒããã®å Žåã¯ãæãæ·±ããã¹ãããããã«ããŒã«åã蟌ãŸããText
ãŠã£ãžã§ããã§ãã ãã®Text
ãŠã£ãžã§ããã¯ãåé¢ãšäžå€®ã«é
眮ãããã®ã§ã¯ãªããã€ã³ãã³ããæ§æãããã³æå³ã®è€æ°ã®ã¬ã€ã€ãŒã«åã蟌ãŸããŠããŸãã ãããã®ã¬ã€ã€ãŒã®1ã€ã«Column
ãŸãã¯Row
ãã¹ããŒãããšãããã«æ·±ããã¹ãããããã®æç¹ã§ã¯ãæãã€ã³ãã³ããããã»ã¯ã·ã§ã³ãŸã§ãã¬ãŒã¹ããã ãã®ã¡ãªããã¯ãããŸããã ã
2çªç®ã®ã³ãŒããããã¯ã§ã¯ãè¿ãããå®éã®ã¬ã³ããªã³ã°å¯èœãªWidget
ã¯é¢æ°ã®äžéšã«ãããããã¯ããã«ããããŸãã ããã«ãOPãææ¡ããæ§æã®ãããªãã®ãããå ŽåãèŠèŠçãªWidget
åžžã«é¢æ°ã®äžéšã«ããããšãæåŸ
ã§ãããããã³ãŒããã¯ããã«äºæž¬å¯èœã§èªã¿ããããªããŸãã
ãã¹ãã£ã³ã°ã«é¢ããŠã¯ã_tree_ãè¡šçŸãããã¹ãã£ã³ã°ãš_sequence_ãè¡šçŸãããã¹ãã£ã³ã°ã«ã¯éãããããŸãã
éåžžã®View -> Text
ãã¹ãã£ã³ã°ãªã©ã®å Žåããã¹ãã£ã³ã°ã¯ç»é¢äžã®èŠªåé¢ä¿ãè¡šããããéèŠã§ãã ã³ã³ããã¹ãïŒFlutterã«ãããã©ããã¯ããããŸããïŒãªã©ã®æ©èœã®å Žåãã³ã³ããã¹ãã®ã¹ã³ãŒããè¡šããŸãã ãããã£ãŠããã¹ãèªäœã¯ãã®ãããªå Žåã«éèŠãªæå³çæå³ãæã¡ãç¡èŠããããšã¯ã§ããŸããã 芪ãšåã®å Žæãå
¥ãæ¿ããŠãçµæãåãã«ãªããšæåŸ
ããããšã¯ã§ããŸããã
ãã ãããã«ããŒã®ãã¹ãïŒReactã§ã¯ãã¬ã³ããªã³ã°ããããããšãåŒã°ããŸãïŒãŸãã¯Promisesã®ãã¹ãã§ã¯ããã¹ãã¯äžé£ã®å€æ/æ¡åŒµãäŒéABuilder -> BBuilder -> CBuilder
ãã¹ãããå Žåããããã®èŠªåé¢ä¿ã¯è¿œå ã®æå³ãäŒããŸããã
以äžã®ã¹ã³ãŒãã§3ã€ã®å€ãã¹ãŠã䜿çšå¯èœã§ããéãããããã®ããªãŒæ§é ã¯å®éã«ã¯é¢ä¿ãããŸããã ããã¯æŠå¿µçã«ããã©ãããã§ããããã¹ãã¯æ§æã®ã¢ãŒãã£ãã¡ã¯ãã«ãããŸããã ãã¡ããããããã¯äºãã®å€ã䜿çšããå ŽåããããŸãïŒãã®å Žåãé åºãéèŠã§ãïŒããããã¯ã·ãŒã±ã³ã·ã£ã«é¢æ°åŒã³åºãã®å Žåã«ãåœãŠã¯ãŸãããã¹ãããã«å®è¡ã§ããŸãã
ãããasync/await
ãé
åçãªçç±ã§ãã äœã¬ãã«ã®ã¡ã«ããºã ã説æããè¿œå æ
å ±ïŒPromisesã®èŠªåé¢ä¿ïŒãåé€ãã代ããã«é«ã¬ãã«ã®ã€ã³ãã³ãïŒã·ãŒã±ã³ã¹ã説æããïŒã«éäžã§ããããã«ããŸãã
ããªãŒã¯ãªã¹ããããæè»ãªæ§é ã§ãã ããããå芪ã«åã1ã€ãããªãå Žåãããã¯ç çåŠçããªãŒã
以åã«ãããã¯å®åæã§ã¯ãªãããšèšã£ãã®ã§ãããã¯å®éã«ã¯èå³æ·±ããã®ã§ãããä»ã§ã¯èªåèªèº«ãšççŸããŠããããã«èŠããŸãã ããã«ã¯2ã€ã®ããšããããšæããŸãã
ãã«ããŒïŒãŸãã¯å°ãªããšãReactã®ã¬ã³ããªã³ã°ããããïŒã¯ãããèªäœããåå©çšå¯èœãªããžãã¯ãåé¡ã®è§£æ±ºçïŒAFAIKïŒã§ãã ãããããããã䜿çšãããšã人éå·¥åŠçã§ã¯ãªããšããã ãã§ãã ã€ã³ãã³ãã«ãã£ãŠãåãã³ã³ããŒãã³ãã§4ã€ãŸãã¯5ã€ä»¥äžã䜿çšããããšã¯åœç¶ãå§ãã§ããŸããã 次ã®åã¬ãã«ã¯èªã¿ãããã®ãããã§ãã
ãããã£ãŠãç§ã«ã¯è§£æ±ºãããŠããªãããã«æãããéšåã¯ããã¹ãã®ãªãŒããŒã³ã¹ããåæžããããšã§ãã ãããŠããã®åŒæ°ã¯async / await
å ŽåãšãŸã£ããåãåŒæ°ã§ãã
次ã®çç±ã«ãããèªã¿ã«ãããªã£ãŠããŸãã
ããã確èªãããã1ã€ã®æ¹æ³ã¯ããã€ã©ãŒãã¬ãŒã以å€ã®ã³ãŒãã匷調衚瀺ããããšã§ããããã¯ãç®ã§ç°¡åã«æ¥œããããã«ã°ã«ãŒãåãããŠããã®ããç®ã§ã¹ãã£ã³ããå¿ èŠãããããã«ã©ãã«ã§ãæ£ãã°ã£ãŠããã®ãã瀺ããŸãã
匷調衚瀺ãããšãããã¯éåžžã«ç°¡åã«æšè«ã§ããŸãã ããããªããšã誰ãäœãã©ãã§äœ¿çšããŠããããææ¡ããåã«ãåé·æ§ã®ãã£ã³ã¯å
šäœãèªã¿åãå¿
èŠããããŸãã
ãããšæ¯èŒãããšã匷調衚瀺ã¯åºæ¬çã«åé·ã§ããç§ã®ç®ãä»ã«è¡ãå Žæããªãããã§ãã
ãããããèªã¿ããããšå¯èªæ§ã«äžäžèŽãããããšã¯æ³šç®ã«å€ããŸãã @Hixieã¯ãã¢ããªã·ãã¯ã¯ã©ã¹ãã¡ã€ã«ã«æéãè²»ãããŠããå¯èœæ§ããããŸããããã§ã¯ã倧èŠæš¡ãªããªãŒãåžžã«èªãã§ç解ããå¿ èŠããããŸãããéåžžã®ã¢ããªéçºè ã¯ãäœçŸãã®å°ããªã¯ã©ã¹ãæ§ç¯ããããšã«
åèãŸã§ã«ãReactã®Contextã«çžåœãããã®ã¯ãæŸæ£ããããŠã£ãžã§ãã/ãããã€ããŒã§ãã
ãããã®å¯äžã®éãã¯ãããã¯ã®åã«åå¿ããå ŽåãBuilderãã¿ãŒã³ã䜿çšããŠã³ã³ããã¹ã/ç¶æ¿ãŠã£ãžã§ããã䜿çšããå¿ èŠããã£ãããšã§ãã
äžæ¹ãFlutterã«ã¯ãåçŽãªé¢æ°åŒã³åºãã§åæ§ç¯ããã€ã³ãããæ¹æ³ããããŸãã
ãããã£ãŠãAttachedWidgetsã䜿çšããŠããªãŒããã©ããåããããã®ããã¯ã¯å¿
èŠãããŸãããããã¯Builderã®åé¡ãåé¿ããçš®é¡ã§ãã
ãã«ããŒãå¿ èŠã«ãªãé »åºŠãå°ãªãããããããããããè°è«ãé£ããçç±ã®1ã€ã§ãã
ããããããã¯ã®ãããªãœãªã¥ãŒã·ã§ã³ãå°å
¥ãããšã httpsïŒ//github.com/flutter/flutter/issues/30062ã®äž¡æ¹ã解決ãããããšã«èšåãã䟡å€ããã
ããã³https://github.com/flutter/flutter/issues/12992
ãŸããFlutterã¯åºæ¬çã«ãã¹ãŠããªãŒã§ãããç§ã®æèŠã§ã¯ä»ã®èšèªãããã¯ããã«å€ãããã @ Hixieã¯æ·±ããã¹ããããããªãŒã®èªã¿åãã«æ £ããŠããããã§ãã ãã¡ãããFlutterèªäœã®äž»èŠãªéçºè ã®1人ãšããŠã圌ã¯ããã«ã€ããŠã¯ããã«å€ãã®çµéšãæã£ãŠããã§ãããã Flutterã¯åºæ¬çã«ã @ HixieãHTML5ä»æ§ãäœæããçµéšããããšæããHTMLã®ããã«ãæ·±ããã¹ããåããå·Šããå³ã®ãã¬ãŒã ã¯ãŒã¯ãšèããããšãã§ããŸãã ã€ãŸããã³ãŒããããã¯ã®å³ç«¯ã®ãã€ã³ãã¯ãã¡ã€ã³ããžãã¯ãšæ»ãå€ãååšããå Žæã§ãã
ããããã»ãšãã©ã®éçºè ã¯ããã§ã¯ãããŸããããŸãã¯ããžãã¯ã¯åã³ããããããã¹ããããæš¹æšã«æ¯ã¹ãŠãäžããäžã«èªãã§ãããã§ãäžã®èšèªäžããæ¥ãŸãã ããã¯ãã³ãŒããããã¯ã®æäžéšã«ãããŸãã ãããã£ãŠã圌ãèªãããã®ã¯ãä»ã®å€ãã®éçºè ã«ãšã£ãŠå¿ ãããããã§ã¯ãããŸããããã®ãããããã§èªã¿ãããã«é¢ããæèŠã®äºåæ³ãèŠãããå¯èœæ§ããããŸãã
ãããèŠãå¥ã®æ¹æ³ã¯ãç§ã®è³ãèŠèŠçã«ç·šéããããã«å¿
èŠãªã³ãŒãã®éã§ãã ç§ã«ãšã£ãŠãããã¯ãããªãŒããè¿ããããã®ã解æããåã«ãè³ãå®è¡ããªããã°ãªããªããããªã声ããæ£ç¢ºã«è¡šããŠããŸãã
ç°¡åã«èšãã°ããã«ããŒããŒãžã§ã³ã¯ãæåéãè¿œå ã®æ å ±ãã³ã³ããã¹ããè¿œå ããã«ãåçŽæ¹åã®ãããããªã³ãã4åé«ããã³ãŒããã¯ããã«ãŸã°ããª/åæ£ããæ¹æ³ã§ããã¯ããŸãã ç§ã®èãã§ã¯ãããã¯ãªãŒãã³ãšã·ã£ããã®ã±ãŒã¹ã§ããããã®çç±ã ãã§å®¢èŠ³çã«èªã¿ã«ãããã€ã³ãã³ãã®åšãã®è¿œå ã®èªç¥çè² è·ããç§ãã¡å šå¡ããã©ãã¿ãŒã§æ±ã£ãŠããäžæ¬åŒ§ã䞊ã¹ãããšããèæ ®ããŠããŸããã
ç§ã®ç®ãç©ºè ¹ã®CPUãšèããŠãã ãããããã¯ãåŠççšã«ããã«æé©åãããŠããŸããïŒ :)
éåžžã®
View -> Text
ãã¹ãã£ã³ã°ãªã©ã®å Žåããã¹ãã£ã³ã°ã¯ç»é¢äžã®_芪åé¢ä¿_ãè¡šãããéèŠã§ãã ã³ã³ããã¹ãïŒFlutterã«ãããã©ããã¯ããããŸããïŒãªã©ã®æ©èœã®å Žåãã³ã³ããã¹ãã®ã¹ã³ãŒããè¡šããŸãã ãããã£ãŠããã¹ãèªäœã¯ãã®ãããªå Žåã«éèŠãªæå³çæå³ãæã¡ãç¡èŠããããšã¯ã§ããŸããã 芪ãšåã®å Žæãå ¥ãæ¿ããŠãçµæãåãã«ãªããšæåŸ ããããšã¯ã§ããŸããã
å®å šã«åæããç§ã¯ããã«ã€ããŠå ã«è¿°ã¹ãŸããã ç¶æ ãæã€è¿œå ã®éããžã¥ã¢ã«ã³ã³ãããŒã©ãŒã䜿çšããŠãããããããžã¥ã¢ã«è¡šç€ºããªãŒã«è¿œå ã®ã³ã³ããã¹ãã¬ã€ã€ãŒãäœæããããšã¯æå³ããããŸããã 5ã€ã®ã¢ãã¡ãŒã¿ãŒã䜿çšããŠããŠã£ãžã§ããã®æ·±ãã¯5å±€ã«ãªããŸãããïŒ ãã®é«ãã¬ãã«ã ãã§ããçŸåšã®ã¢ãããŒãã¯ã¡ãã£ãšèããããŸãã
ããã§ç§ã«é£ã³åºã2ã€ã®åé¡ããããŸãã
é«äŸ¡ãªãªãœãŒã¹ã䜿çšããå Žåããããã©ãã»ã©é£ãã/æ瀺çã§ãããã«ã€ããŠãããã€ãã®æèŠã®çžéãããã®ã§ã¯ãªãããšæããŸãã Flutterã®å²åŠã¯ãéçºè ããããããã€ã©ã®ããã«äœ¿çšããããçå£ã«èããããã«ãããå°é£/æ瀺çã«ããå¿ èŠããããšãããã®ã§ãã ã¹ããªãŒã ãã¢ãã¡ãŒã·ã§ã³ãã¬ã€ã¢ãŠããã«ããŒãªã©ã¯ãç°¡åããããšéå¹ççã«äœ¿çšãããå¯èœæ§ã®ããéèŠãªã³ã¹ããè¡šããŠããŸãã
ãã«ãã¯åæã§ãããã¢ããªéçºè ãšããŠæ±ãæãèå³æ·±ããã®ã¯éåæã§ãã ãã¡ããããã«ããéåæã«ããããšã¯ã§ããŸããã Stream / Animation / FutureBuilderã®ãããªãããã®äŸ¿å©ãªæ©èœãäœæããŸããããéçºè ãå¿ èŠãšãããã®ã«å¯ŸããŠåžžã«ååã«æ©èœãããšã¯éããŸããã ããããããã¬ãŒã ã¯ãŒã¯ã§StreamãFutureBuilderãããŸã䜿çšããŠããªãããšã瀺ããŠããŸãã
ãã¡ãããéåææäœãæäœãããšãã¯ãåžžã«ã«ã¹ã¿ã ã¬ã³ããªã³ã°ãªããžã§ã¯ããäœæããããã«éçºè ã«æ瀺ããã®ã解決çã§ã¯ãªããšæããŸãã ãããããã®ãã°ã§ç§ãèŠãŠããäŸã§ã¯ãéåæãšåæã®äœæ¥ãæ··åšããŠãããããåŸ ã¡ãããŸããã ãã«ãã¯ããã¹ãŠã®åŒã³åºãã§äœããçæããå¿ èŠããããŸãã
fwiwãReactããŒã ã¯ãèªã¿ãããã®åé¡ã1ã€ã®åæ©ãšããŠåå©çšããããšã«åãçµã¿ãŸããã
ããã¯ã®åæ©ïŒã³ã³ããŒãã³ãéã§ã¹ããŒããã«ããžãã¯ãåå©çšããã®ã¯é£ãã
Reactã¯ãåå©çšå¯èœãªåäœãã³ã³ããŒãã³ãã«ãã¢ã¿ãããããæ¹æ³ãæäŸããŠããŸãã...ããã解決ããããšãããã¿ãŒã³ã«ç²ŸéããŠãããããããŸãã...ã ãã ãããããã®ãã¿ãŒã³ã§ã¯ãã³ã³ããŒãã³ãã䜿çšãããšãã«ã³ã³ããŒãã³ããåæ§ç¯ããå¿
èŠããããŸããããã¯ãç
©éã§ãã³ãŒãã远跡ããã®ãé£ãããªãå¯èœæ§ããããŸãã
ããã¯ãFlutterãçŸåšãã€ãã£ãã«ãç¶æ ãæ§æãããæ¹æ³ãæäŸããŠããªãæ¹æ³ãšéåžžã«ãã䌌ãŠããŸãã ãŸããç§ãã¡ãã«ããŒãã¬ã€ã¢ãŠãããªãŒãå€æŽããæäœãããé¢åã«ãªãããåŸãã®ãé£ãããªãããšããšã³ãŒãçºçããŸãã
@dnfield build
æ¯ååŒã³åºãå¿
èŠãããå Žåã¯ãããã¯ãbuild
ã¡ãœããã«å«ãŸãªãããã«ããŠããã«ããåžžã«åæãããããã«ããããšãã§ããŸããã€ãŸãã initState
ã¯ã©ã¹å
ã«ããã¯ãé
眮ããŸãã dispose
ã¯ã§ãã ããã¯ãæžã人ãããããããããšã«åé¡ã¯ãããŸããïŒ
Promises / Futuresã«ã€ããŠãåãè°è«ãããããšãã§ãã
await
ã¯Promiseãè¿ããšããäºå®ãèŠãé ããŠãããšèšãããšãã§ããŸãã
ããããããŸããã Awaitã¯ãæåéã1ã€ã®æ©èœã®åãªãæ§æç³è¡£ã§ãã åé·ãªFuturesãŸãã¯å®£èšåæ§æã䜿çšããå Žåãã³ãŒãã®__intent__ã¯åãã§ãã
ããã§ã®èŠæ±ã¯ããŸã£ããç°ãªãæžå¿µã«å¯ŸåŠãããœãŒã¹ã³ãŒããåãåã®äžã«ç§»åããããããçš®é¡ã®ç°ãªãåäœã1ã€ã®ããŒã¯ãŒãã®èåŸã«é ããäœããã®åœ¢ã§èªç¥çè² è·ã軜æžãããšäž»åŒµããããšã§ãã
ããã¯å®å šã«èª€ãã§ãããã®ããŒã¯ãŒãã䜿çšãããã³ã«ãçµæãéââåææäœãå®è¡ããããäžèŠãªåæ§ç¯ãããªã¬ãŒããããé·æéæå¹ãªãªããžã§ã¯ããåæåãããããããã¯ãŒã¯åŒã³åºããè¡ã£ããããã£ã¹ã¯ãããã¡ã€ã«ãèªã¿åã£ãããéçãªå€ãè¿ãããããã®ãã©ããçåã«æãå¿ èŠããããŸãã ã ãããã¯ãã¹ãŠéåžžã«ç°ãªãç¶æ³ã§ããã䜿çšããŠããããã¯ã®ãã¬ãŒããŒã«ç²ŸéããŠããå¿ èŠããããŸãã
ããã§ã®ã»ãšãã©ã®éçºè
ã¯ãå®è£
ã®è©³çŽ°ãæ°ã«ããã«ãããã®ãããã¯ãã䜿çšã§ããããããã®ãããªè©³çŽ°ã«ç
©ããããããšãå«ããç°¡åãªéçºãæãã§ããããšãè°è«ããç解ããŠããŸãã
ãã®ãããããããã¯ããå®å
šãªæå³ãç解ããã«æå°æªã«äœ¿çšãããšãéå¹ççã§æªãã³ãŒãã«ã€ãªããã人ã
ãèªåã®è¶³ãæã¡æ®ºãåå ã«ãªããŸãããããã£ãŠããåå¿è
éçºè
ã®ä¿è·ãã®åé¡ãã解決ããŸããã
ãŠãŒã¹ã±ãŒã¹ãåçŽãªå Žåã¯ãããã§ããããã¯ãæ°ãŸãŸã«äœ¿çšã§ããŸãã ãã«ããŒã¯å¥œããªã ã䜿çšããŠãã¹ãã§ããŸãããã¢ããªãè€éã«ãªããã³ãŒãã®åå©çšãå°é£ã«ãªããããç¬èªã®ã³ãŒããšã¢ãŒããã¯ãã£ã«ãã£ãšæ³šæãæãå¿ èŠããããšæããŸãã æœåšçã«æ°çŸäžäººã®ãŠãŒã¶ãŒåãã®ã¢ããªãäœæããŠããå ŽåãéèŠãªè©³çŽ°ãæœè±¡åãããéæ³ãã䜿çšããããšãéåžžã«èºèºããŸãã ä»ã®ãšãããFlutterã®APIã¯éåžžã«åçŽãªãŠãŒã¹ã±ãŒã¹ã«ã¯åçŽã§ããã誰ã§ãéåžžã«å¹ççãªæ¹æ³ã§ããããçš®é¡ã®è€éãªããžãã¯ãå®è£ ã§ããæè»æ§ãåããŠããŸãã
@Rudikszç¹°ãè¿ããŸããã誰ãããªãã«ããã¯ãžã®ç§»åã匷å¶ããŠããŸããã çŸåšã®ã¹ã¿ã€ã«ã¯åŒãç¶ãååšããŸãã ãã®ç¥èã«çŽé¢ããŠããªãã®è°è«ã¯äœã§ããïŒ
ãšã«ãããè€æ°ã®ããã¯ãäœããã®åœ¢ã§ã¢ããªããããã¯ããŠããããšã確èªããåŸã§ããå¹ççãªã³ãŒããèšè¿°ã§ããŸãã çŸåšã®ã¹ã¿ã€ã«ã®å Žåãšåãããã«ããããã¡ã€ãªã³ã°ããããã¢ããªãå®è¡ããããããšè¡šç€ºãããŸãã
@Rudikszç¹°ãè¿ããŸããã誰ãããªãã«ããã¯ãžã®ç§»åã匷å¶ããŠããŸããã çŸåšã®ã¹ã¿ã€ã«ã¯åŒãç¶ãååšããŸãã ãã®ç¥èã«çŽé¢ããŠããªãã®è°è«ã¯äœã§ããïŒ
ããããã®åãè°è«ã¯ããã¬ãŒã ã¯ãŒã¯ã®åé¡ã«ã€ããŠäžå¹³ãèšã£ãŠãã人ã ã«ãåœãŠã¯ãŸããŸãã ããã¯ããã±ãŒãžã䜿çšããªãããã«åŒ·å¶ããŠãã人ã¯èª°ãããŸããã
ç§ã¯ããã§éåžžã«éããªããŸãã
ãã®åé¡ã¯ãããã¯ãã¹ããŒããã«ãŠã£ãžã§ãããããã³èª°ãäœã䜿çšãããã«é¢ãããã®ã§ã¯ãªãã5è¡å°ãªãã³ãŒããèšè¿°ã§ããããã«ããããã«æ°å幎ã®ãã¹ããã©ã¯ãã£ã¹ãå
ã«æ»ãããšã«é¢ãããã®ã§ãã
ããªãã®è°è«ã¯å®éã«ã¯æ©èœããŸããã ãã®åé¡ãçºçããçç±ã¯ãçŸåšã®ã¢ãã«ããã§ã«ãã¬ãŒã ã¯ãŒã¯ã«ãã€ãã£ãã«ååšããŠãããããflutter_hooksããã±ãŒãžããã¬ãŒã ã¯ãŒã¯ã«äœããå«ããããšã§å¯èœãªãã¹ãŠã®ããšãå®è¡ããªãããã§ãã è°è«ã¯ãflutter_hooksã®æ©èœããã¬ãŒã ã¯ãŒã¯ã«ãã€ãã£ãã«ç§»åããããšã§ãã ããªãã®è°è«ã¯ãç§ãçŸåšã®ã¢ãã«ã§ã§ããããšã¯äœã§ããããã¯ããã±ãŒãžã§ãã§ãããšä»®å®ããŠããŸãããããã¯çå®ã§ã¯ãããŸããããã®è°è«ã®ä»ã®äººããã®ããã§ãã ããããçã§ããå Žåãããã¯æ©èœããŸããããã¯ãããã¯ããã€ãã£ãã«ãã¬ãŒã ã¯ãŒã¯ã«ããããšãæå³ããŸãããããã£ãŠãããã¯ãšéããã¯ã¯åçã§ãããããããã¯ããŒã¹ãšåæ§ã«çŸåšã®ã¢ãã«ã䜿çšã§ããŸããã¢ãã«ãããã¯ç§ã䞻匵ããŠãããã®ã§ãã
ã³ãŒããèªã¿ãããããããšããã¹ããã©ã¯ãã£ã¹ã§ãããé床ã®ãã¹ãã¯ã¢ã³ããã¿ãŒã³ã§ããããšãããã£ãŠããããããã¹ããã©ã¯ãã£ã¹ãã©ãããæ¥ãŠããã®ãããããŸããã ã©ã®ãã¹ããã©ã¯ãã£ã¹ãæ£ç¢ºã«åç §ããŠããŸããïŒ
fwiwãReactããŒã ã¯ãèªã¿ãããã®åé¡ã1ã€ã®åæ©ãšããŠåå©çšããããšã«åãçµã¿ãŸããã
ããã¯ã®åæ©ïŒã³ã³ããŒãã³ãéã§ã¹ããŒããã«ããžãã¯ãåå©çšããã®ã¯é£ãã
Reactã¯ãåå©çšå¯èœãªåäœãã³ã³ããŒãã³ãã«ãã¢ã¿ãããããæ¹æ³ãæäŸããŠããŸãã...ããã解決ããããšãããã¿ãŒã³ã«ç²ŸéããŠãããããããŸãã...ã ãã ãããããã®ãã¿ãŒã³ã§ã¯ãã³ã³ããŒãã³ãã䜿çšãããšãã«ã³ã³ããŒãã³ããåæ§ç¯ããå¿ èŠããããŸããããã¯ãç ©éã§ãã³ãŒãã远跡ããã®ãé£ãããªãå¯èœæ§ããããŸãã
FlutterãReactãããã¯ããã«çŽ æŽãããããšã«ã€ããŠã¿ããªã絶è³ããŠããã®ãèããŠããŸãã ãã¶ãããã¯Reactã®ããã«ãã¹ãŠãè¡ãããã§ã¯ãªãããã§ããïŒ äž¡æ¹ã®æ¹æ³ã䜿çšããããšã¯ã§ããŸãããFlutterãReactãããã¯ããã«é²ãã§ãããšã¯èšããŸããããŸããReactãšãŸã£ããåãããã«ãã¹ãŠãå®è¡ããããã«äŸé Œããããšãã§ããŸããã
Flutterãç¹å®ã®åé¡ã«äœ¿çšããããšã決å®ãããœãªã¥ãŒã·ã§ã³ã¯ãããèªäœã®ã¡ãªããã«åºã¥ããŠããå¿ èŠããããŸãã ç§ã¯Reactã«ç²ŸéããŠããŸããããã©ãããç§ã¯ããã€ãã®æ¬åœã«çŽ æŽããããã¯ãããžãŒãèŠéããŠããããã§ãã ïŒ/
FlutterãReactã®ãããªãã¹ãŠãè¡ãã¹ãã ãšäž»åŒµããŠãã人ã¯ããªããšæããŸãã
ãããå®éã«ã¯ãFlutterã®ãŠã£ãžã§ããã¬ã€ã€ãŒã¯Reactãã倧ãã圱é¿ãåããŠããŸãã ããã¯å
¬åŒææžã«èšèŒãããŠããŸãã
ãã®çµæããŠã£ãžã§ããã«ã¯Reactã³ã³ããŒãã³ããšåãå©ç¹ãšåãåé¡ã®äž¡æ¹ããããŸãã
ããã¯ãReactããããã®åé¡ã«å¯ŸåŠããäžã§Flutterãããå€ãã®çµéšãæã£ãŠããããšãæå³ããŸãã
ããã¯åœŒãã«ãã£ãšé·ãçŽé¢ãã圌ããããããç解ããŸããã
ãããã£ãŠãFlutteråé¡ã®è§£æ±ºçãReactåé¡ã®è§£æ±ºçãšé¡äŒŒããŠããããšã¯é©ãã¹ãããšã§ã¯ãããŸããã
@Rudiksz Flutterã®ãŠãŒã¶ãŒAPIã¯ãå éšAPIãç°ãªãå Žåã§ããReactã®ã¯ã©ã¹ããŒã¹ã¢ãã«ãšéåžžã«ãã䌌ãŠããŸãïŒç°ãªããã©ããã¯ããããŸããããå éšAPIã«å®éã«
ãããã®é¡äŒŒæ§ãèãããšãäžèšã®ããã«ãåé¡ã®è§£æ±ºçãé¡äŒŒããŠããããã«èŠããã®ã¯åœç¶ã®ããšã§ãã
ã©ããããäºãã«æŠããªãããã«é 匵ããŸãããã
æŠããç§ãã¡ãå°ãå¯äžã®ããšã¯ããã®è°è«ã殺ãã解決çãèŠã€ããããªãããšã§ãã
FlutterãReactãããã¯ããã«çŽ æŽãããããšã«ã€ããŠã¿ããªã絶è³ããŠããã®ãèããŠããŸãã ãã¶ãããã¯Reactã®ããã«ãã¹ãŠãè¡ãããã§ã¯ãªãããã§ããïŒ äž¡æ¹ã®æ¹æ³ã䜿çšããããšã¯ã§ããŸãããFlutterãReactãããã¯ããã«é²ãã§ãããšã¯èšããŸããããŸããReactãšãŸã£ããåãããã«ãã¹ãŠãå®è¡ããããã«äŸé Œããããšãã§ããŸããã
ReactããŒã ãããã¯ãæãã€ãããšãã«åæ§ã®åæ©ãæã£ãŠããããšãææããããã§è¡šæããŠããæžå¿µãæ€èšŒããŸãã ãã®ã¿ã€ãã®ã³ã³ããŒãã³ãããŒã¹ã®ãã¬ãŒã ã¯ãŒã¯å ã§å ±éã®ã¹ããŒããã«ããžãã¯ãåå©çšããã³çµåããéã«åé¡ãããããšã確ãã«æ€èšŒããŸãããŸããå¯èªæ§ããã¹ããããã³ãã¥ãŒã®ãã¯ã©ãã¿ãŒãã«é¢ããäžè¬çãªåé¡ã«é¢ããè°è«ãããçšåºŠæ€èšŒããŸãã
ç§ã¯Reactã§åããããšããªããFlutterã倧奜ãã§ãã ããã§åé¡ãç°¡åã«ç¢ºèªã§ããŸãã
@Rudikszå®è·µãããŸã§ããããå®éã«ããã©ãŒãã³ã¹ãçºæ®ãããã©ããã¯
@Hixieããã¯ã HookWidget
ãšStatefulWidget
äž¡æ¹ã§userIdãããŠãŒã¶ãŒã®ããã¯ããŒã ã衚瀺ãããŠã£ãžã§ãããå®è£
ããããã«äžè¬çãªãã©ãã¿ãŒãŠãŒã¶ãŒãæã€å¯èœæ§ã®ããæ
ã®äŸã§ãã
__ããã¯ãŠã£ãžã§ãã__
String useUserNickname(Id userid) {
final name = useState("");
useEffect(async () {
name.value = "Loading...";
name.value = await fetchNicknames()[userId;
}, [userId]);
return name.value;
}
class UserNickname extends HookWidget {
final userId;
Widget build(BuildContext context) {
final nickname = useUserNickname(userId);
return Text(nickname);
}
}
__ã¹ããŒããã«ãŠã£ãžã§ãã__
class UserNickname extends Widget {
final userId;
// ... createState() ...
}
class UserNicknameState extends State {
String nickname= "";
initState() {
super.initState();
fetchAndUpdate();
}
fetchAndUpdate() async {
setState(() { this.nickname = "Loading..." });
final result = await fetchNicknames()[widget.userId];
setState(() { this.nickname = result });
}
void didUpdateWidget(oldWidget) {
if (oldWidget.userId != widget.userId) {
fetchAndUpdate();
}
}
Widget build(BuildContext context) {
return Text(this.nickname);
}
}
ãããŸã§ã®ãšããèå³æ·±ããã®ã¯äœããããŸããã ã©ã¡ãã®ãœãªã¥ãŒã·ã§ã³ãããªãåãå
¥ããããç°¡åã§ããã©ãŒãã³ã¹ãé«ãã§ãã
ä»ãç§ãã¡ã¯å©çšãããUserNickname
å
éšã§ListView
ã ã芧ã®ãšãããfetchNicknamesã¯ã1ã€ã®ããã¯ããŒã ã ãã§ãªããããã¯ããŒã ã®ããããè¿ããŸãã ãããã£ãŠãæ¯ååŒã³åºãã®ã¯åé·ã§ãã ããã§é©çšã§ããããã€ãã®ãœãªã¥ãŒã·ã§ã³ïŒ
fetchNicknames()
ããžãã¯ã®åŒã³åºãã芪ãŠã£ãžã§ããã«ç§»åããçµæãä¿åããŸããæåã®è§£æ±ºçã¯åãå
¥ããããŸããã2ã€ã®åé¡ããããŸãã
1- UserNickname
ã¯ããã¹ããŠã£ãžã§ããã«ãããªãããã圹ã«ç«ããªããªããŸããå¥ã®å Žæã§äœ¿çšããå Žåã¯ã芪ãŠã£ãžã§ããïŒ ListView
ïŒã§è¡ã£ãããšãç¹°ãè¿ãå¿
èŠããããŸãã ã ããã¯ããŒã ã衚瀺ããããã®ããžãã¯ã¯UserNickname
å±ããŠããŸãããåå¥ã«ç§»åããå¿
èŠããããŸãã
2-ä»ã®å€ãã®ãµãããªãŒã§fetchNicknames()
ã䜿çšããå¯èœæ§ããããããã¢ããªã±ãŒã·ã§ã³ã®äžéšã ãã§ãªãããã¹ãŠã®ã¢ããªã«å¯ŸããŠãã£ãã·ã¥ããããšããå§ãããŸãã
ãããã£ãŠããã£ãã·ã¥ãããŒãžã£ãŒãéžæãã CacheManager
ã¯ã©ã¹ã«InheritedWidgets
ãŸãã¯Provider
ãŸãã
ãã£ãã·ã¥ã®ãµããŒããè¿œå ããåŸïŒ
__ããã¯ãŠã£ãžã§ãã__
String useUserNickname(Id userid) {
final context = useContext();
final cache = Provider.of<CacheManager>(context);
final name = useState("");
useEffect(async () {
name.value = "Loading...";
var cachedValue = cache.get("nicknames");
if (cachedValue == null || cachedValue[widget.userId] == null) {
final result = await fetchNicknames();
cache.set("nicknames", result );
cachedValue = result ;
}
final result = cachedValue[widget.userId];
name.value = result ;
}, [userId]);
return name.value;
}
class UserNickname extends HookWidget {
final userId;
Widget build(BuildContext context) {
final nickname = useUserNickname(userId);
return Text(nickname);
}
}
__ã¹ããŒããã«ãŠã£ãžã§ãã__
class UserNickname extends Widget {
final userId;
// ... createState() ...
}
class UserNicknameState extends State {
String nickname= "";
CacheManager cache;
initState() {
super.initState();
fetchAndUpdate();
this.cache = Provider.of<CacheManager>(context);
}
fetchAndUpdate() async {
setState(() { this.nickname = "Loading..." });
var cachedValue = this.cache.get("nicknames");
if (cachedValue == null || cachedValue[widget.userId] == null) {
final result = await fetchNicknames();
this.cache.set("nicknames", result );
cachedValue = result ;
}
final result = cachedValue [widget.userId];
setState(() { this.nickname = result });
}
void didUpdateWidget(oldWidget) {
if (oldWidget.userId != widget.userId) {
fetchAndUpdate();
}
}
Widget build(BuildContext context) {
return Text(this.nickname);
}
}
ããã¯ããŒã ãå€æŽããããšãã«ã¯ã©ã€ã¢ã³ãã«éç¥ãããœã±ãããµãŒããŒããããŸãã
__ããã¯ãŠã£ãžã§ãã__
String useUserNickname(Id userid) {
final context = useContext();
final cache = Provider.of<CacheManager>(context);
final notifications = Provider.of<ServiceNotifications>(context);
final name = useState("");
fetchData() async {
name.value = "Loading...";
var cachedValue = cache.get("nicknames");
if (cachedValue == null || cachedValue[widget.userId] == null) {
final result = await fetchNicknames();
cache.set("nicknames", result );
cachedValue = result ;
}
final result = cachedValue[widget.userId];
name.value = result ;
}
useEffect(() {
final sub = notifications.on("nicknameChanges", fetchData);
return () => sub.unsubscribe();
}, [])
useEffect(fetchData, [userId]);
return name.value;
}
class UserNickname extends HookWidget {
final userId;
Widget build(BuildContext context) {
final nickname = useUserNickname(userId);
return Text(nickname);
}
}
__ã¹ããŒããã«ãŠã£ãžã§ãã__
class UserNickname extends Widget {
final userId;
// ... createState() ...
}
class UserNicknameState extends State {
String nickname= "";
CacheManager cache;
ServerNotification notifications;
CancelableOperation sub;
initState() {
super.initState();
fetchAndUpdate();
this.cache = Provider.of<CacheManager>(context);
this.notifications = Provider.of<ServerNotification>(context);
this.sub = notifications.on("nicknameChanges", fetchAndUpdate);
}
dispose() {
super.dispose();
this.sub.unsubscribe();
}
fetchAndUpdate() async {
setState(() { this.nickname = "Loading..." });
var cachedValue = this.cache.get("nicknames");
if (cachedValue == null || cachedValue[widget.userId] == null) {
final result = await fetchNicknames();
this.cache.set("nicknames", result );
cachedValue = result ;
}
final result = cachedValue [widget.userId];
setState(() { this.nickname = result });
}
void didUpdateWidget(oldWidget) {
if (oldWidget.userId != widget.userId) {
fetchAndUpdate();
}
}
Widget build(BuildContext context) {
return Text(this.nickname);
}
}
ãããŸã§ã®ãšãããäž¡æ¹ã®å®è£
ã¯åãå
¥ãå¯èœã§ãããè¯å¥œã§ãã çµ±èšçãªãã®ã®IMOãã€ã©ãŒãã¬ãŒãã¯ãŸã£ããåé¡ãããŸããã ãã®åé¡ã¯ããŠãŒã¶ãŒã®ããã¯ããŒã ãšã¢ãã¿ãŒã®äž¡æ¹ãæã€UserInfo
ãããªãŠã£ãžã§ãããå¿
èŠãªå Žåã«çºçããŸãã ãŸãããWelcome [username]ãã®ãããªæã§è¡šç€ºããå¿
èŠãããããã UserNickname
ãŠã£ãžã§ããã䜿çšããããšã¯ã§ããŸããã
__ããã¯ãŠã£ãžã§ãã__
useFetchUserNickname(userId) // old code
useUserAvatar(userId) // implementation like `useFetchUserNickname`
class UserNickname extends HookWidget {
final userId;
Widget build(BuildContext context) {
final nickname = useUserNickname(userId);
final avatar = useUserAvatar(userId);
return Row(
children: [Image.network(avatar), Text(nickname)],
);
}
}
ãããã__ã¹ããŒããã«ãŠã£ãžã§ãã__ã®å Žåãäœæããããžãã¯ã ãã䜿çšããããšã¯ã§ããŸããã ããžãã¯ãã¯ã©ã¹ïŒææ¡ããProperty
ãªã©ïŒã«ç§»åããå¿
èŠããããŸãããããã§ãæ°ãããŠã£ãžã§ããã§ããããã£ã¯ã©ã¹ã䜿çšããŠãŠã£ãžã§ããã®æ¥çå€ãå床äœæããå¿
èŠããããŸãã
æåã®3ã€ã®äŸã§å€æŽãèŠãããå Žåãå¿
èŠãªå€æŽã¯ç¶æ
ããžãã¯ã®ã¿ã§ãããå€æŽãè¡ã£ãå Žæã¯ãã¹ãŠç¶æ
ããžãã¯ã§ãã£ãããããŠã£ãžã§ããèªäœã¯ãŸã£ããå€æŽããŠããŸããã
ããã«ãããã©ãã§ã䜿çšã§ãããã¯ãªãŒã³ãªïŒæèŠã®ããïŒæ§æå¯èœã§å®å
šã«åå©çšå¯èœãªç¶æ
ããžãã¯ãåŸãããŸããã
IMHOã®å¯äžã®åé¡ã¯ã useUserNickname
åŒã³åºãããšã§ããããã¯ã1ã€ã®é¢æ°ã§ããã ãã®ããšãã§ããããã§ãã
ããããæ¬çªç°å¢ã«ãã2ã€ã®ã¢ããªïŒããã¯ãå€çšããŠããïŒã§flutter_hooks
ãåå¿ãããŠäœ¿çšããé·å¹Žã®çµéšãããé©åãªç¶æ
管çãè¡ãããŠããªãããšãããããŸãïŒMobXããã®ä»ã®ç¶æ
管çãœãªã¥ãŒã·ã§ã³ãè©ŠããŸããããŠã£ãžã§ããã®æ¥çå€ã¯åžžã«ããã«ãããŸãïŒã¯ã¯ããã«æãã§ãã ããã³ããšã³ãã¢ããªã®ç»é¢ããšã«5ããŒãžã®ããã¥ã¡ã³ããäœæããå¿
èŠã¯ãããŸãããã¢ããªã®ããŒãžãã©ã®ããã«æ©èœããããç解ããããã«ãæåã®ãªãªãŒã¹ããæ°ãæ以å
ã«å°ããªæ©èœãè¿œå ããå¿
èŠãããå ŽåããããŸãã ã¢ããªããµãŒããŒãåŒã³åºããããŸããïŒ ç°¡åãªã¿ã¹ã¯é¢é£ããããã¯ã«ç§»åããŠå€æŽãããšãã¢ããªå
šäœããã®ããã¯ã䜿çšãããããã¢ããªå
šäœãä¿®æ£ãããŸãã åªããæœè±¡åãåããããã¯ã䜿çšããªããŠããã¢ããªã§åæ§ã®ããšãè¡ãããšãã§ããŸãããç§ãèšã£ãŠããã®ã¯ãããã¯ã¯ãã®åªããæœè±¡åã§ãããšããããšã§ãã
@gaearonã¯ç§ãããããŸã
äžèšã®äŸãèŠããšãäžèšã®ã¡ãœããïŒã¹ããŒããã«ãŠã£ãžã§ãããšããã¯ãŠã£ãžã§ããïŒã®ã©ãããä»ã®ã¡ãœãããããããã©ãŒãã³ã¹ãåªããŠããŸããã ããããèŠç¹ã¯ããããã®1ã€ããããã©ãŒãã³ã¹ã®é«ãã³ãŒããæžãããšã人ã ã«å¥šå±ããŠãããšããããšã§ãã
ãŸãã次ã®ãããªæŽæ°ïŒã¢ãã¡ãŒã·ã§ã³ãªã©ïŒãå€ãããå Žåã¯ã StreamBuilder
ããã«æŽæ°ããå¿
èŠããããµãããªãŒã®ã¿ãæŽæ°ããããšãã§ããŸãã
1- HookWidget
ãšStatefulWidget/StatelessWidget
äž¡æ¹ã§å®å
šã«å®è¡å¯èœãªãªãã·ã§ã³ã§ããæ°ãããŠã£ãžã§ãããäœæããã ãã§ã
2-芪ãŠã£ãžã§ãããšåãŠã£ãžã§ããã®ããŒã¿ãéåžžã«ç·å¯ã«çµåãããŠããããã flutter_hooks
ããã±ãŒãžã§HookWidgetBuilder
ã«é¡äŒŒãããã®ã䜿çšããŸãã
è£è¶³ïŒãã®ãããã¯ã«ã€ããŠè°è«ãããã®åé¡ã«ããã»ã©å€ãã®ãšãã«ã®ãŒã泚ãã§ããã@Hixieãš@rrousselGitã«æ¬åœã«æè¬ããŠããŸãã ãããã®äŒè«ã®çµæãå¿ãã楜ãã¿ã«ããŠããŸãã
@Hixieã®åºçºç¹ã«åºã¥ããŠãç§ã¯ããªãã¯ãŒã«ã§ãšã¬ã¬ã³ããªãã®ãèããŠããŸãã ãŸã å ±æããæºåãæŽã£ãŠããŸããããããªããŸãšããªã³ãŒããµã³ãã«ãäœæã§ããã®ã§ãéåžžã«ç°è³ªã«èŠããããã¯ãããapplesïŒapplesãæ¯èŒããæ¹ãç°¡åã ãšæããŸãã
ãããã£ãŠã次ã®çœ²åãæã€StatefulWidgetããããšæ³åããŠãã ããã
class ExampleSimple extends StatefulWidget {
final Duration duration1;
final Duration duration2;
final Duration duration3;
const ExampleSimple({Key key, this.duration1, this.duration2, this.duration3}) : super(key: key);
<strong i="9">@override</strong>
_ExampleSimpleState createState() => _ExampleSimpleState();
}
ããã©ã¢ãã¡ãŒã¿ãŒã³ã³ãããŒã©ãŒã䜿çšããŠç¶æ ãå®è£ ãããšã次ã®ããã«ãªããŸãã
class _ExampleSimpleVanillaState extends State<ExampleSimpleVanilla> with SingleTickerProviderStateMixin {
AnimationController _anim1;
AnimationController _anim2;
AnimationController _anim3;
<strong i="13">@override</strong>
void initState() {
_anim1 = AnimationController(duration: widget.duration1, vsync: this);
_anim1.forward();
_anim2 = AnimationController(duration: widget.duration2, vsync: this);
_anim2.forward();
_anim3 = AnimationController(duration: widget.duration3, vsync: this);
_anim3.forward();
super.initState();
}
<strong i="14">@override</strong>
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.symmetric(vertical: _anim2.value * 20, horizontal: _anim3.value * 30,),
color: Colors.red.withOpacity(_anim1.value),
);
}
<strong i="15">@override</strong>
void didUpdateWidget(ExampleSimpleVanilla oldWidget) {
if (oldWidget.duration1 != widget.duration1) {
_anim1.duration = widget.duration1;
}
if (oldWidget.duration2 != widget.duration2) {
_anim1.duration = widget.duration1;
}
if (oldWidget.duration3 != widget.duration3) {
_anim1.duration = widget.duration1;
}
super.didUpdateWidget(oldWidget);
}
<strong i="16">@override</strong>
void dispose() {
_anim1.dispose();
_anim2.dispose();
_anim3.dispose();
super.dispose();
}
}
StatefulPropertyã䜿çšããŠäœæãããšã次ã®ããã«ãªããŸãã
class _ExampleSimpleState extends State<ExampleSimple> with StatefulPropertyManager {
StatefulAnimationProperty _anim1;
StatefulAnimationProperty _anim2;
StatefulAnimationProperty _anim3;
<strong i="6">@override</strong>
void initStatefulProperties({bool firstRun = false}) {
_anim1 = initProperty(_anim1, StatefulAnimationProperty(duration: widget.duration1, playOnInit: true));
_anim2 = initProperty(_anim2, StatefulAnimationProperty(duration: widget.duration2, playOnInit: true));
_anim3 = initProperty(_anim3, StatefulAnimationProperty(duration: widget.duration3, playOnInit: true));
super.initStatefulProperties(firstRun: firstRun);
}
<strong i="7">@override</strong>
Widget build(BuildContext context) {
return Container(
margin: EdgeInsets.symmetric(vertical: _anim2.controller.value * 20, horizontal: _anim3.controller.value * 30,),
color: Colors.red.withOpacity(_anim1.controller.value),
);
}
}
ããã§ã®éãã«é¢ããããã€ãã®æ³šæïŒ
代ããã«ãStatefulPropertyManagerã®æ©èœãç解ããå¿ èŠããããŸãããããã¯äžåºŠåŠç¿ããŠããããã¿ã€ãã®ãªããžã§ã¯ãã«é©çšããããšãéèŠã§ããSingleTickerProviderMixinã¯ãäž»ã«Animator Controllerã®äœ¿çšã«åºæã§ããããã¹ãŠã®ã³ã³ãããŒã©ãŒã«ç¬èªã®ããã·ã³ã°ãããã䜿çšãç°¡åã«ãªããé¢åã«ãªããŸãã ããããã¹ãŠãç¥ã£ãŠããåå¥ã®ãStatefulObjectsããæã£ãŠããã ãã§ïŒãã«ããŒãšåãããã«ïŒïŒãã¯ããã«ã¯ãªãŒã³ã§æ¡åŒµæ§ãé«ããªããŸãã
StatefulAnimationPropertyã®ã³ãŒãã¯æ¬¡ã®ããã«ãªããŸãã
class StatefulAnimationProperty extends BaseStatefulProperty<StatefulAnimationProperty> implements TickerProvider {
final Duration duration;
final TickerProvider vsync;
final bool playOnInit;
StatefulAnimationProperty({<strong i="7">@required</strong> this.duration, <strong i="8">@required</strong> this.vsync, this.playOnInit = false});
AnimationController get controller => _controller;
AnimationController _controller;
Ticker _ticker;
<strong i="9">@override</strong>
Ticker createTicker(onTick) {
_ticker ??= Ticker((elapsed)=>handleTick(elapsed, onTick));
return _ticker;
}
handleTick(Duration elapsed, TickerCallback onTick) {
managerWidget.buildWidget(); //TODO: This just calls setState() on the host widget. Is there some better way to do this?
onTick(elapsed);
}
<strong i="10">@override</strong>
void init(StatefulAnimationProperty old) {
_controller = old?.controller ??
AnimationController(
duration: duration ?? Duration(seconds: 1),
vsync: vsync ?? this,
);
if (playOnInit && old?.controller == null) {
_controller.forward();
}
super.init(old);
}
<strong i="11">@override</strong>
void update(StatefulAnimationProperty old) {
if (duration != old.duration) {
_controller.duration = duration;
}
if (vsync != old.vsync) {
_controller.resync(vsync);
}
super.update(old);
}
<strong i="12">@override</strong>
void dispose() {
_controller?.dispose();
_ticker?.dispose();
super.dispose();
}
}
æåŸã«ã泚ç®ã«å€ããã®ã¯ãæ¡åŒµæ©èœã䜿çšãããšèªã¿ããããããã«åäžããããã次ã®ãããªãã®ã«ããããšãã§ããŸãã
void initStatefulProperties({bool firstRun = false}) {
_anim1.init(duration: widget.duration1, playOnInit: true);
_anim2.init(duration: widget.duration2, playOnInit: true);
_anim3.init(duration: widget.duration3, playOnInit: true);
super.initStatefulProperties(firstRun: firstRun);
}
[ç·šé]ç§èªèº«ã®äž»åŒµããããã®ããã«ãç§ã®ããã©ã®äŸã«ã¯ãã°ããããŸãã didUpdateWidgetã®åã¢ãã¡ãŒã¿ãŒã«æ£ããæéãæž¡ãã®ãå¿ããŸããã ã³ãŒãã¬ãã¥ãŒã§èª°ãæ°ã¥ããªãã£ããšãããããã®ãã°ãå®éã«èŠã€ããã®ã«ã©ããããã®æéãããããŸãããïŒ èªãã§ãããšãã«èª°ãããããèŠã€ããŸããã§ãããïŒ ããããã®ãŸãŸã«ããŠããããšã¯ãçŸå®ã®äžçã§èµ·ãã£ãŠããããšã®å®ç§ãªäŸã§ãã
ãããé³¥ç°å³ã§ããã€ã©ãŒãã¬ãŒããèµ€ã§ããŒã¯ãããŠããŸãã
ãããçŽç²ãªå®åæã§ããã°ããã»ã©æªãã¯ãªããã³ã³ãã€ã©ãŒã¯ãããæ¬ èœããŠãããšããªãã«æ鳎ããŸããã ããããããã¯ãã¹ãŠãªãã·ã§ã³ã§ãïŒ ãŸããçç¥ããå Žåããã°ãçºçããŸãã ãããã£ãŠãããã¯å®éã«ã¯éåžžã«æªãç¿æ £ã§ãããDRYã§ã¯ãããŸããã ããããã«ããŒã®åºçªã§ãããåçŽãªãŠãŒã¹ã±ãŒã¹ã«ã®ã¿é©ããŠããŸãã
ããã«ã€ããŠç§ãéåžžã«èå³æ·±ããšæãã®ã¯ã100è¡ãšStateãžã®åçŽãªããã¯ã¹ã€ã³ããæ¢åã®ã¯ã©ã¹ã®æãåé·ã«ããæ¹æ³ã§ãã ããšãã°ãTickerProviderMixinsã䜿çšããå¿ èŠã¯ã»ãšãã©ãããŸããã ãµãã³ã³ããã¹ããå®éã«äœæãããå Žåãé€ããŠãTweenAnimationBuilderã䜿çšããå¿ èŠã¯ã»ãšãã©ãããŸããã ãã©ãŒã«ã¹ã³ã³ãããŒã©ãŒãtextInputã³ã³ãããŒã©ãŒã®ç®¡çãªã©ãåŸæ¥ã®å€ãã®åé¡ç¹ã¯å€§å¹ ã«ç·©åãããŠããŸãã Streamsã䜿çšãããšãã¯ããã«é åçã§äžåšçšã«ãªããŸãã ã³ãŒãããŒã¹å šäœã§ããã«ããŒã®äœ¿çšãäžè¬çã«æžããããšãã§ããŸããããã«ãããããç°¡åã«æš¹æšãååŸã§ããããã«ãªããŸãã
ãŸããåè¿°ã®FetchUserã®äŸã®ããã«ãç¬èªã®ã«ã¹ã¿ã ç¶æ ãªããžã§ã¯ãã_éåžžã«_ç°¡åã«äœæã§ããŸããããã«ã¯ãçŸåšåºæ¬çã«ãã«ããŒãå¿ èŠã§ãã
ããã¯ã次ã®Flutter DeveloperSurveyã§å°ããéåžžã«èå³æ·±ã質åã«ãªããšæããŸãã
ããã¯è¯ãã¹ã¿ãŒãã«ãªãã§ãããã ãã®åé¡ãããŸããŸãªéšå/質åã«åããŠããããFlutteréçºè ã解決ãããæ¬åœã®åé¡ã§ãããã©ããã確èªããŠãã ããã
ãããæ確ã«ãªããšããã®äŒè©±ã¯ããæµæ¢ã§è±ãã«ãªããŸã
åã³ã¡ã³ãã®äžã®çµµæåã®åå¿ã¯ãã³ãã¥ããã£ããããåé¡ãšèŠãªããŠãããã©ããã«ã€ããŠæ確ãªèãã瀺ããŠããŸãã ãã®åé¡ã«ã€ããŠ250以äžã®é·ãã³ã¡ã³ããèªãã éçºè ã®æèŠã¯ãå€ãã®ç§èŠãæå³ããŸãã
@esDotDevããã¯ç§ã
ç§ãèŠåŽããŠããäž»ãªããšã¯ããããå¹ççãªæ¹æ³ã§è¡ãæ¹æ³ã§ãã ããšãã°ãValueListenableBuilderã¯ãããã©ãŒãã³ã¹ã枬å®å¯èœã«åäžãããããã«äœ¿çšã§ããååŒæ°ãåããŸãã ããããã£ã¢ãããŒãã§ãããè¡ãæ¹æ³ãããããŸããã
@Hixie
ãã®ãããªã¢ãããŒãã«ããå¹çã®äœäžã¯é¿ããããªãããã«æãããããšãç解ããŠããŸãã ããããã³ãŒãããããã¡ã€ãªã³ã°ããåŸã®æé©åãšããFlutterã®èãæ¹ã奜ãã§ãã ããããã£ã¢ãããŒãã®æ確ããšç°¡æœãããæ©æµãåããã¢ããªã±ãŒã·ã§ã³ã¯ãããããããŸãã ã³ãŒãããããã¡ã€ãªã³ã°ãããã«ããŒã«ãªãã¡ã¯ã¿ãªã³ã°ãããããŠã£ãžã§ããã®äžéšãç¬èªã®ãŠã£ãžã§ããã«åé¢ããããããªãã·ã§ã³ã¯åžžã«ãããŸãã
ããã¥ã¡ã³ãã¯ããã¹ããã©ã¯ãã£ã¹ãåæ ãããã¬ãŒããªããæ確ã«ããå¿ èŠããããŸãã
ç§ãèŠåŽããŠããäž»ãªããšã¯ããããå¹ççãªæ¹æ³ã§è¡ãæ¹æ³ã§ãã ããšãã°ãValueListenableBuilderã¯ãããã©ãŒãã³ã¹ã枬å®å¯èœã«åäžãããããã«äœ¿çšã§ããååŒæ°ãåããŸãã ããããã£ã¢ãããŒãã§ãããè¡ãæ¹æ³ãããããŸããã
ããŒããããããã£ã®å šäœçãªãã€ã³ãã¯éèŠèŠçãªãªããžã§ã¯ãã®ããã ãšæããŸãã äœããããªãŒã«ã³ã³ããã¹ãã¹ããããæã¡ããå Žåãããã¯ãã«ããŒã§ããå¿ èŠããããŸãïŒå®éããããã¯ä»ç§ãæããã«ããŒã§ããå¿ èŠãããå¯äžã®ãã®ã§ããïŒïŒ
ãããã£ãŠããã¥ãŒå šäœããã€ã³ãããã ãã®å Žåã«ã»ãšãã©ã®å Žåã«äœ¿çšããStatefulValueListenablePropertyããããŸãã 次ã«ãããªãŒã®ãµãã»ã¯ã·ã§ã³ãåæ§ç¯ããå¿ èŠãããå Žåã«åããŠãValueListenableBuilderãçšæããŸãã
ãã«ããŒããªãŒãããŒããšããŠäœ¿çšããããšã¯ããŠã£ãžã§ããããªãŒã®äžéšã«2ã€ãŸãã¯3ã€ããã¹ãããã»ã©èªã¿ããããæãªãããšã¯ãªããããããã¯ãã¹ãã®åé¡ã«ã察åŠããŸãã
@TimWhiting Flutterã®èšèšå²åŠã®å€§éšåã¯ã人ã ãæ£ããéžæã«å°ãããšã§ãã ããã©ãŒãã³ã¹ãåäžãããããã«é¢ããªããã°ãªããªãã¹ã¿ã€ã«ã«åŸãããã«äººã ã奚å±ããããšã¯é¿ããããšæããŸãã äžåºŠã«ãã¹ãŠã®ããŒãºã«å¯Ÿå¿ããæ¹æ³ã¯ãªããããããŸããããç§ãã¡ã¯ééããªããããè©ŠããŠã¿ãå¿ èŠããããŸãã
@Hixie
ãã«ããŒã«ãšã£ãŠãã®ãããªãã®ã¯ã©ãã§ããïŒ
class _ExampleSimpleState extends State<ExampleSimple> with StatefulPropertyManager {
StatefulAnimationProperty _anim1;
StatefulAnimationBuilderProperty _anim2;
<strong i="7">@override</strong>
void initStatefulProperties({bool firstRun = false}) {
_anim1 = initProperty(_anim1, StatefulAnimationProperty(duration: widget.duration1, playOnInit: true));
_anim2 = initProperty(_anim3, StatefulAnimationBuilderProperty(duration: widget.duration3, playOnInit: true));
super.initStatefulProperties(firstRun: firstRun);
}
<strong i="8">@override</strong>
Widget build(BuildContext context) {
return Container(
color: Colors.red.withOpacity(_anim1.controller.value),
child: _anim2(child: SomeChildWidget()),
);
}
}
詳现ãæããŠããã ããŸããïŒ ææ¡ãããããããŸããã
圌ã¯ãStatefulPropertyããèŠèŠçãªã³ã³ããŒãã³ããæã€ããããã£ã«ãªãã·ã§ã³ã®ãã«ãã¡ãœãããæäŸã§ãããšèšã£ãŠãããšæããŸãã
return Column(
children: [
TopContent(),
_valueProperty.build(SomeChildWidget()),
]
)
ããã¯ããªãð¥imoã
ã¯ãããããæ©èœãããã©ããã¯ããããŸããããbuildã¡ãœããã¯ããã«ããŒã®ä»ã®ããããã£ãããããã£ã«ãã£ãŠèšå®ãããããšãé€ããŠãéåžžã®ãã«ããŒãšåãããã«åãåããŸãã
ãã«ããŒããã®ã³ã³ããã¹ããå¿
èŠãªå Žåãbuildã¡ãœããã¯ã³ã³ããã¹ããæäŸãããã«ããŒåŒæ°ãåãå
¥ããŸãã
å éšçã«ã¯ãã¡ãœããã¯æå®ãããããããã£ã䜿çšããŠéåžžã®ãã«ããŒãäœæããååŒæ°ãéåžžã®ãã«ããŒã«æž¡ããŠãããè¿ãå ŽåããããŸãã
ããªãããã®ã³ãŒããæã£ãŠãããšããŸãããïŒ
Widget build(BuildContext context) {
return ExpensiveParent(
child: ValueListenableBuilder(
valueListenable: foo,
child: ExpensiveChild(),
builder: (BuildContext context, value, Widget child) {
return SomethingInTheMiddle(
value: value,
child: child,
);
}
),
);
}
...ãããã©ã®ããã«å€æããŸããïŒ
@esDotDevããããã£èªäœããã£ãã«ãŒãããã€ããŒã«ãããšããããªãã®ã¢ã€ãã¢ã奜ãã§ãããç§ã¯ãããèæ ®ããŠããŸããã§ããã
ãã®ããã¯ã¹ã¿ã€ã«ã®ã¢ãããŒãã®æã匷åãªåŽé¢ã®1ã€ã¯ãã¹ããŒããã«ããžãã¯ã_å®å šã«_ã«ãã»ã«åã§ããããšã§ãã ãããã£ãŠããããã®å ŽåãACã®å®å šãªãªã¹ãã¯æ¬¡ã®ãšããã§ãã
çŸåšãéçºè ã1ã3ã4ãæåã§ç¹°ãè¿ãåŠçããïŒãŸãã¯åŠçããªãïŒããšãšã2ãš5ãåŠçããåéæ³ã®SingleTickerProviderMixinïŒãthisããvsyncãšããŠæž¡ãããšã§ãäœã¶æãæ··ä¹±ããŸããïŒ ïŒã ãŸããSingleTickerProviderMixinèªäœã¯ãæããã«ãã®ã¿ã€ãã®åé¡ã®ä¿®æ£ãè©Šã¿ããã®ã§ãããã以å€ã®å Žåã¯ãã¯ã©ã¹ããšã«TickerProviderãå®è£ ããã ãã§ãªããã¯ããã«æ確ã«ãªããŸãã
ããªãããã®ã³ãŒããæã£ãŠãããšããŸãããïŒ
Widget build(BuildContext context) { return ExpensiveParent( child: ValueListenableBuilder( valueListenable: foo, child: ExpensiveChild(), builder: (BuildContext context, value, Widget child) { return SomethingInTheMiddle( value: value, child: child, ); } ), ); }
...ãããã©ã®ããã«å€æããŸããïŒ
class _ExampleSimpleState extends State<ExampleSimple> with StatefulPropertyManager {
StatefulValueListenableBuilder _fooBuilder;
<strong i="10">@override</strong>
void initStatefulProperties({bool firstRun = false}) {
_fooBuilder = initProperty(StatefulValueListenableProperty(valueListenable: widget.foo));
super.initStatefulProperties(firstRun: firstRun);
}
<strong i="11">@override</strong>
Widget build(BuildContext context) {
return ExpensiveParent(
child: SomethingInTheMiddle(
_fooBuilder.value,
_fooBuilder.builder(childBuilder: () => ExpensiveChild()),
),
);
}
}
@Hixie
äŸãããããšãã ç§ã¯ããã«ãã¹ãã·ã§ãããäžããŸããã ç§ã¯äœããéãããããããŸããã
泚æãã¹ãéèŠãªç¹ã¯ããã«ããŒãåããã£ãã·ã¥ããããšã§ãã åé¡ã¯ããã€å®éã«åäŸãå建ããå¿ èŠãããã®ãââãšããããšã§ãã ãããããªããæèµ·ããããšããŠãã質åã ã£ããšæããŸãã
@Hixieã¯https://github.com/flutter/flutter/issues/51752#issuecomment-671104377ãèŠãããšããã
æ¬åœã«è¯ãç¹ãããã€ããããšæããŸãã
ç§ã¯ä»æ¥ãããããã®ValueListenableBuilderã䜿ã£ãŠäœããæ§ç¯ããŠããŸãããèªãã®ã¯è¯ããªããšããèšââããŸããã
@Hixie
äŸãããããšãã ç§ã¯ããã«ãã¹ãã·ã§ãããäžããŸããã ç§ã¯äœããéãããããããŸããã
ããããã£ã¯å®çŸ©ãããŠããç¶æ ã«ãã€ã³ããããããããããæ©èœãããšã¯æããªããããExpensiveParentã¯åžžã«ããã§åæ§ç¯ãããŸãã 次ã«ãåã®ãã£ãã·ã¥ãåé¡ããããšæããŸããBuilderã®äŸã§ã¯ã芪ã®ç¶æ ãæ§ç¯ããããšãã«ã®ã¿åãåæ§ç¯ããããšãããã£ãŠããŸããããã®ã¡ãœããã§ã¯ãããããã£ã¯ãã£ãã·ã¥ãç¡å¹ã«ããã¿ã€ãã³ã°ãèªèããŠããŸããïŒãã ããããã¯ããããããã§ãïŒè§£æ±ºå¯èœã§ããïŒïŒ
ããããtbhãããã¯ãæ°ããã³ã³ããã¹ããå°å ¥ãããå Žåã®ãã«ããŒã®å®ç§ãªãŠãŒã¹ã±ãŒã¹ã§ãã StatefulPropertiesïŒçŽç²ãªç¶æ ïŒãšStatefulWidgetsïŒç¶æ ãšã¬ã€ã¢ãŠãã®çµã¿åããïŒã®ã³ã³ããã¹ããæã€ããšã¯éåžžã«ãšã¬ã¬ã³ãã ãšæããŸãã
æå³çã«ãµãã³ã³ããã¹ããäœæãããšãã¯ãã€ã§ããå®çŸ©äžãããªãŒã®ããã«äžã§äœæããŸããããã¯ããã«ããŒã®äž»ãªæ¬ ç¹ã®1ã€ïŒããªãŒå šäœã§ã®åŒ·å¶çãªãã¹ãïŒãšæŠãã®ã«åœ¹ç«ã¡ãŸãã
@escamoteur ïŒãããŠãã®ã³ã¡ã³ããæžãã@sahandevs ïŒããç§ã¯ä»¥åã«ãããå匷ããŠããŸããã ããã¯ç¢ºãã«äººã ãåé€ãããçš®é¡ã®è«çã瀺ãã®ã«åœ¹ç«ã€ãšæããŸãã ãã ããäŸèªäœã¯å°ãçããããšæããŸããã»ãšãã©ã®ããžãã¯ïŒããšãã°ããã£ãã·ã¥ã«é¢ãããã¹ãŠïŒãã¢ããªç¶æ ã®ããžãã¹ããžãã¯ã«ããããŠã£ãžã§ããã®è¿ãã«ã¯ãªããšäºæ³ããŸãã ãŸããããããªããŒããäžæããã«ããã®ã³ã¡ã³ãã§ææ¡ãããŠããã»ã©ç°¡æœãªæ§æãååŸããããã®è¯ãæ¹æ³ãããããŸããïŒããšãã°ã䜿çšããŠããããã¯ã®æ°ãå€æŽããå ŽåããªããŒãå šäœã§ã¹ããŒããã«ã«ä¿ã€æ¹æ³ãæ確ã§ã¯ãããŸããïŒã
ããã¯èšã£ãŠããäžèšã®@esDotDevãš@TimWhitingã®äœæ¥ã¯éåžžã«èå³æ·±ããã®ã§ããããããã®åé¡ã解決ã§ãããšæããŸãã ããã¯ã»ã©çãã¯ãããŸããããä¿¡é Œæ§ã¯é«ããªããŸãã ãã®ãããªãã®ãããã±ãŒãžåããããšã¯å®å šã«çã«ããªã£ãŠãããšæããŸããããŸãæ©èœããã°ãFlutterFavoriteã«ãªãå¯èœæ§ããããŸãã ããããã£ã®æ§ç¯ã«é¢ããè€éããšããã©ãŒãã³ã¹ãžã®åœ±é¿ãããã³ããŸããŸãªäººã ãããŸããŸãªã¹ã¿ã€ã«ãã©ã®ããã«å¥œãããèæ ®ãããšãæ¹åã¯ããã»ã©éèŠã§ã¯ãªããããã³ã¢ãã¬ãŒã ã¯ãŒã¯æ©èœãšããŠæå³ããããã©ããã¯ããããŸããã çµå±ã®ãšãããããŸããŸãªäººã ãããŸããŸãªã¹ã¿ã€ã«ã䜿çšããããšã¯åé¡ãªãã¯ãã§ãããã³ã¢ãã¬ãŒã ã¯ãŒã¯ã«è€æ°ã®ã¹ã¿ã€ã«ãæãããããªãã®ã§ãæ°ããéçºè ã«ãšã£ãŠã¯èª€è§£ãæãã ãã§ãã
FlutterãåŠã¶æ£ããæ¹æ³ã¯ãæ§æãæœè±¡åããã®ã§ã¯ãªããæåã«ãŠã£ãžã§ãããç解ãã次ã«ãŠã£ãžã§ãããæœè±¡åããããŒã«ïŒããã¯ãªã©ïŒãåŠã¶ããšã§ãããšããè°è«ããããŸãã ããããªããšãã·ã¹ãã ãã©ã®ããã«æ©èœãããã«ã€ããŠã®éèŠãªèŠçŽ ãæ¬ èœããŠãããããããã©ãŒãã³ã¹ã®é«ãã³ãŒããæžããšããç¹ã§è¿·ãå¯èœæ§ããããŸãã
ãŸããããããªããŒããäžæããã«ããã®ã³ã¡ã³ãã§ææ¡ãããŠããã»ã©ç°¡æœãªæ§æãååŸããããã®è¯ãæ¹æ³ãããããŸããïŒããšãã°ã䜿çšããŠããããã¯ã®æ°ãå€æŽããå ŽåããªããŒãå šäœã§ã¹ããŒããã«ã«ä¿ã€æ¹æ³ãæ確ã§ã¯ãããŸããïŒã
ããã¯ã¯åé¡ãªãããããªããŒãã§åäœããŸãã
äžèŽããªãruntimeTypeãæã€æåã®ããã¯ã«ãããåŸç¶ã®ãã¹ãŠã®ããã¯ãç Žæ£ãããŸãã
ããã¯ãè¿œå ãåé€ãããã³äžŠã¹æ¿ãããµããŒãããŸãã
çŸåšååšããéšåçãªæœè±¡åãããå®å šãªæœè±¡åã®æ¹ãæãŸãããšããè°è«ããããšæããŸãã
ããããã£ã®ã³ã³ããã¹ãã§ã¢ãã¡ãŒã¿ãŒãã©ã®ããã«æ©èœããããç解ãããå Žåã¯ããããå®å šã«ç¡èŠããããé£ã³èŸŒãã§ãã ãããããã¯ãã¹ãŠåé¡ãªããèªå·±å®çµåã§äžè²«æ§ããããŸãã
StatefulWidgetã®ã³ã³ããã¹ãã§AnimatorControllerãã©ã®ããã«æ©èœããããç解ãããå Žåã¯ãåºæ¬çãªã©ã€ããµã€ã¯ã«ããã¯ãç解ããå¿ èŠããããŸãããåºç€ãšãªããã£ãã¯ã¡ã«ããºã ãã©ã®ããã«æ©èœããããç解ããå¿ èŠã¯ãããŸããã ããã¯ããæå³ã§äž¡æ¹ã®äžçã®äžã§ææªã§ãã ããããæ£ããæ©èœããããã«ã¯ååãªéæ³ã§ã¯ãããŸããããæ°ãããŠãŒã¶ãŒãæ··ä¹±ãããããã€ãã®ããã¯ã¹ã€ã³ïŒããèªäœã¯ã»ãšãã©ã®æ°ããæŠå¿µã§ãïŒãšéæ³ã®vsyncããããã£ãç²ç®çã«ä¿¡é Œããããã«åŒ·å¶ããã®ã«ååã§ãã
ã³ãŒãããŒã¹ã®ä»ã®äŸã¯ããããŸããããããã¯ãStatefulWidgetã«ããã€ãã®ãã«ããŒããã¯ã¹ã€ã³ãæäŸãããŠããç¶æ³ã«åœãŠã¯ãŸããŸãããåžžã«å®è¡ããå¿ èŠã®ããä»ã®ããŒãã¹ãã©ãããããã€ããããŸãã Dev'sã¯ããŒãã¹ãã©ããïŒéå±ãªéšåïŒãåŠç¿ããMixinïŒèå³æ·±ã/è€éãªãããïŒãç¡èŠããŸã
ããã¯èšã£ãŠããäžèšã®@esDotDevãš@TimWhitingã®äœæ¥ã¯éåžžã«èå³æ·±ããã®ã§ããããããã®åé¡ã解決ã§ãããšæããŸãã ããã¯ã»ã©çãã¯ãããŸããããããä¿¡é Œæ§ããããŸã
ããã¯ã©ã®ããã«ä¿¡é Œæ§ãé«ããªããŸããïŒ
æªãç¶æ
ã«ãªãå¯èœæ§ããããããæ¡ä»¶ä»ããŸãã¯ã©ã€ããµã€ã¯ã«å€ã§ããããã£ãäœæ/æŽæ°ããããšã¯ã§ããŸããã ããšãã°ãæ¡ä»¶ä»ãã§ããããã£ãåŒã³åºããšãæ¡ä»¶ãfalseã®å Žåã«ããããã£ãç Žæ£ãããŸããã
ãŸãããã¹ãŠã®ããããã£ã¯ãåæ§ç¯ã®ãã³ã«åè©äŸ¡ãããŸãã
ãã ããNNBDåŸã®ãã¹ãŠã®å Žæã§ãŠãŒã¶ãŒã«!
䜿çšã匷å¶ããããæŽæ°åã«ãŠãŒã¶ãŒã«ããããã£ãžã®ã¢ã¯ã»ã¹ãèš±å¯ããããããªã©ãè€æ°ã®åé¡ãçºçããŸãã
ããšãã°ã誰ããdidUpdateWidget
å
ã®ããããã£ãèªã¿åã£ãå Žåã¯ã©ããªããŸããïŒ
initProperties
ã¯ã©ã€ããµã€ã¯ã«ã®åã«å®è¡ãããŸãããïŒ ãã ããããã¯ããã«ãããšã«ããããã£ãè€æ°åæŽæ°ããå¿
èŠãããå¯èœæ§ãããããšãæå³ããŸããinitProperties
ã¯didUpdateWidgetã®åŸã«å®è¡ãããŸãããïŒ æ¬¡ã«ãdidUpdateWidgetå
ã®ããããã£ã䜿çšãããšãå€ãç¶æ
ã«ãªãå¯èœæ§ããããŸããããã£ãŠãæçµçã«ã¯ãããã¯ã®ãã¹ãŠã®åé¡ãçºçããŸããã次ã®ããã«ãªããŸãã
çµå±ãäžããããäŸã¯ã以äžãšåäœã«éãã¯ãããŸããã
class Example extends StatelessWidget {
<strong i="29">@override</strong>
Widget build(context) {
final value1 = keyword TweenAnimationBuilder(tween: Tween(begin: 0, end: 1));
final value2 = keyword TweenAnimationBuilder(tween: Tween(begin: 0, end: 1));
final value3 = keyword TweenAnimationBuilder(tween: Tween(begin: 0, end: 1));
return Container(
margin: EdgeInsets.symmetric(vertical: value2 * 20, horizontal: value3 * 30),
color: Colors.red.withOpacity(value1),
child: _anim2(child: SomeChildWidget()),
);
}
}
ãã ãããã®æ§æã¯æ¬¡ã®ãããªå€ãã®ããšããµããŒãããŸãã
class Example extends StatelessWidget {
<strong i="34">@override</strong>
Widget build(context) {
final value1 = keyword TweenAnimationBuilder(tween: Tween(begin: 0, end: 1));
if (condition) {
return Container();
}
final value2 = keyword TweenAnimationBuilder(tween: Tween(begin: 0, end: 1));
...
}
}
condition
ãfalseã«åãæ¿ãããšã value2
condition
ç Žæ£ãããŸã
Widget build(context) {
final foo = keyword FooBuilder();
final bar = keyword BarBuilder();
return Text('$foo $bar');
}
次ã®ããã«å€æŽã§ããŸãã
Builder<String> LabelBuilder() builder* {
final foo = keyword FooBuilder();
final bar = keyword BarBuilder();
return '$foo $bar';
}
Widget build(context) {
final label = keyword LabelBuilder();
return Text(label);
}
child
ãã©ã¡ãŒã¿ãŒã¯åŒãç¶ãå®è¡å¯èœã§ãã
Widget build(context) {
final value = keyword StreamBuilder();
return Builder(
builder: (context, child) {
final value2 = keyword TweenAnimationBuilder();
final value = keyword ValueListenableBuilder();
return Whatever(child: child);
},
child: ExpensiveChild()
);
}
èšèªã®äžéšãšããŠãããã®ããã®ã·ã³ã¿ãã¯ã¹ã·ã¥ã¬ãŒãæã€ããšããã§ããŸãïŒ
Widget build(context) {
return Scaffold(
body: {
final value = keyword TweenAnimationBuilder();
final value2 = keyword ValueListenableBuilder();
return Text();
},
);
}
èšèªã®äžéšãšããŠã次ã®ãããªã·ããªãªããµããŒãã§ããŸãã
Widget build(context) {
String label;
if (condition) {
label = keyword LabelBuilder();
} else {
label = keyword AnotherBuilder();
}
final value2 = keyword WhateverBuilder();
return ...
}
ããŸã䟿å©ã§ã¯ãããŸãããããµããŒããããŠããŸããæ§æãã³ã³ãã€ã«ãããŠãããããä»ã®æ¹æ³ã§ã¯å©çšã§ããªãã¡ã¿ããŒã¿ã«äŸåããããšã§ã keyword
å䜿çšæ³ãåºå¥ã§ããŸãã
ãã«ããŒã®èªã¿ãããã«é¢ããŠãããã¯åã®äŸã§ããããã«ããŒã§è¡ãããŸãã ããã¯ä¿¡é Œæ§ãšã³ãŒã䜿çšã®ããŒãºã®ãã¹ãŠã解決ããŸããããããç§ã®è²§åŒ±ãªãŠã£ãžã§ããããªãŒã«äœãããããèŠãŠãã ããïŒ 'ïŒ
class _ExampleSimpleBuilderState extends State<ExampleSimpleBuilder> {
<strong i="6">@override</strong>
Widget build(BuildContext context) {
return TweenAnimationBuilder<double>(
tween: Tween(begin: 0, end: 1),
duration: widget.duration1,
builder: (_, value1, __) {
return TweenAnimationBuilder<double>(
tween: Tween(begin: 0, end: 1),
duration: widget.duration2,
builder: (_, value2, __) {
return TweenAnimationBuilder<double>(
tween: Tween(begin: 0, end: 1),
duration: widget.duration3,
builder: (_, value3, __) {
return Container(
margin: EdgeInsets.symmetric(vertical: value2 * 20, horizontal: value3 * 30),
color: Colors.red.withOpacity(value1),
);
});
});
});
}
}
éèŠãªã³ãŒããèŠã€ããã®ã¯ïŒå°ãªããšãç§ã®ç®ã«ã¯ïŒã¯ããã«å°é£ã§ãã ãŸãããããæžããšãã¯ãã©ã®ãã©ã±ãããã©ãã«ããã®ããã»ãã³ãã³ãã©ãã«çœ®ãã¹ãããªã©ãåžžã«æ··ä¹±ããŠããã®ã§ã3åã»ã©ããçŽãå¿ èŠããããŸããããã¹ãããããã«ããŒã¯ãå éšã§æžãããäœæ¥ãããããã®ãé¢çœããããŸããã 1ã€ã®ééã£ãã»ãã³ãã³ãšdartfmtãã€ã«ãããã¹ãŠãå®å šã«æŒãã€ã¶ããŸãã
ããã¯ã©ã®ããã«ä¿¡é Œæ§ãé«ããªããŸããïŒ
ããã¯ããããã³ã¢ãã©ã°ã€ã³imoã§ããå¿ èŠãããçç±ã®å®ç§ãªäŸã§ãã ããã§å¿ èŠãªãã¡ã€ã³ç¥èã¯_deep_ã§ãã ç§ã¯ããã®ãããªåçŽãªãã£ãã·ã³ã°ã·ã¹ãã ãå®è£ ããããã®ã¹ã¯ãªããã®ç¥èãæã£ãŠããŸãããçºçããå¯èœæ§ã®ãããã¹ãŠã®ãšããžã±ãŒã¹ããŸãã¯çºçããå¯èœæ§ã®ããæªãç¶æ ãç¥ãããã®ãã¡ã€ã³ç¥èããæã£ãŠããŸããã ã¬ã以å€ã«ããFlutterããŒã ã®å€ã«ãã®ããšãç¥ã£ãŠããéçºè ã4人ãããšæããŸãïŒ ïŒæããã«èªåŒµããŠããŸãïŒã
ã¹ããŒãã¬ã¹ãŠã£ãžã§ããã®ãµããŒãã®åé¡ã¯è¯ãåé¡ã§ãã äžæ¹ã§ãStatefulWidgetsã¯å¥åŠãªããšã«åé·ã§ãã äžæ¹ãããã§ã¯ãçŽç²ãªåé·æ§ã«ã€ããŠçã«è©±ããŸãã 2ã€ã®ã¯ã©ã¹ãå®çŸ©ããªããã°ãªããªãããšããçºçããå¯èœæ§ã®ãããã°ã¯ãªãããããå°ç¡ãã«ããæ¹æ³ã¯ãããŸãããã³ã³ãã€ã©ãŒã¯ãããèš±å¯ããŸãããStatelessWidgetã§ããããããšã¯äœããããŸããã ã ããç§ã¯ããã倧ããªåé¡ã§ããããšã«å£²ãããŠããŸãã...確ãã«æã£ãŠããã°ããã®ã§ãããããã¯æåŸã®5ïŒ imoã§ãããè¡ãè©°ãŸããã®ã§ã¯ãããŸããã
äžæ¹ãããŒã¯ãŒãããµããŒãããremiã®æ§æã¯ã絶察ã«çŸããããã¡ããã¡ãæè»ã§åŒ·åã§ãã ãããŠããããããªãã«ç¡æã§StatelessWidgetã®ãµããŒããæäŸãããªããããã¯ãã äœåã§ãð¥
StatelessWidgetã®ãµããŒãã¯å€§ããªIMOã§ãã ãªãã·ã§ã³ã§ãããããã§ãéåžžã«ã¯ãŒã«ã§ãã
ããã¯éèŠã§ã¯ãªãããšã«åæããŸããã人ã
ã¯ãã§ã«StatelessWidgetã®ä»£ããã«é¢æ°ã䜿çšããããšãããã£ãŠäºã£ãŠããŸãã
ãã«ããŒã䜿çšããããã«StatefulWidgetã䜿çšããããã«äººã
ã«èŠæ±ããããšã¯ïŒã»ãšãã©ã®ãã«ããŒãåçã®ããããã£ãæã£ãŠããå¯èœæ§ãé«ãããïŒã競åãæ·±ããã ãã§ãã
ããã ãã§ãªããdartã§é«éé¢æ°ãäœæã§ããäžçïŒhttps://github.com/dart-lang/language/issues/418ïŒã§ã¯ãã¯ã©ã¹ãå®å šã«åãé€ãããšãã§ããŸãã
<strong i="9">@StatelessWidget</strong>
Widget Example(BuildContext context, {Key key, String param}) {
final value = keyword StreamBuilder();
return Text('$value');
}
ãã®åŸã次ã®ããã«äœ¿çšãããŸãã
Widget build(context) {
// BuildContext and Key are automatically injected
return Example(param: 'hello');
}
ããã¯ã function_widgetã«ãã£ãŠãµããŒããããŠãããã®ã§ããããã¯ãé¢æ°ãèšè¿°ããŠã¯ã©ã¹ãçæããã³ãŒããžã§ãã¬ãŒã¿ãŒã§ããã HookWidget
ããµããŒãããŠããŸãã
éãã¯ãDartã§é«éé¢æ°ããµããŒãããããšã§ããã®ãããªæ§æããµããŒãããããã®ã³ãŒãçæã®å¿ èŠæ§ããªããªãããšã§ãã
@Hixieãããä¿¡é Œã§ãããšã¯
ããããããŒã¯ãŒãã䜿ã£ãææ¡ããããŸããã æ°ããããŒã¯ãŒãã®ã±ãŒã¹ã¯éåžžã«åŒ·ããšæããŸãã
ç§ãæ°ã«å ¥ããªãã®ã¯ãããã€ãã®åçŽãªãªããžã§ã¯ãã«ããããã£ãè€æ°å/ãã«ãã§èšå®ããã³ã¹ãã«ã€ããŠå¿é ããŠããããšã§ãããåºæ¬çã«100äžã¬ãã«ã®ã³ã³ããã¹ããšå€§éã®ã¬ã€ã¢ãŠãã³ã¹ããäœæãããœãªã¥ãŒã·ã§ã³ãæå±ããŠããŸãã ç§ã¯èª€è§£ããŠããŸããïŒ
ãã1ã€ã®æ¬ ç¹ã¯ããã®éæ³ã®èãæ¹ã§ãã ããããäœãäžæè°ãªããšãããã€ãããªããæ°ããããŒã¯ãŒãã¯ãããæãéããã®ã«å¹æçãªæ¹æ³ã ãšæããŸããããã¯ãã³ãã¥ããã£ã匷調ããŠåŒã³ããããããäœã§ãããããããŠãããã©ã®ããã«æ©èœãããã説æããã®ãç°¡åã«ããããã§ãã åºæ¬çã«ã¯ãFlutterã§æ¬¡ã®å¹Žã«åããŠèª°ãã話ãåãããšã«ãªãã§ãããããããããçãŸããã¯ãŒã«ãªãã©ã°ã€ã³ãççºçã«å¢ãããšç¢ºä¿¡ããŠããŸãã
@Hixieãããä¿¡é Œã§ãããšã¯
ãã ããããã¯ã¯éçã«åæå¯èœã§ããããããã®ãããªåé¡ã¯çºçããŸããããããã£ãŠãããã¯ã誀çšãããšãã³ã³ãã€ã«ãšã©ãŒãçºçããå¯èœæ§ããããŸãã
ããã¯åé¡ã§ã¯ãããŸãã
åæ§ã«ãã«ã¹ã¿ã ãšã©ãŒãçºçããªãå Žåã¯ãåè¿°ããããã«ãããããã£ã«ã¯ãŸã£ããåãåé¡ãçºçããŸãã
åççã«æžãããšã¯ã§ããŸããïŒ
Property property;
<strong i="12">@override</strong>
void initProperties() {
if (condition) {
property = init(property, MyProperty());
}
}
condition
ãtrueããfalseã«åãæ¿ããŠããããããã£ã¯ç Žæ£ãããªãããã§ãã
ã«ãŒãã§åŒã³åºãããšãã§ããŸããã ããã¯1åéãã®å²ãåœãŠã§ãããããå®éã«ã¯æå³ããããŸããã ããããã£ãã«ãŒãã§å®è¡ãããŠãŒã¹ã±ãŒã¹ã¯äœã§ããïŒ
ãããŠãããããã£ãä»»æã®é åºã§èªã¿åãããšãã§ãããšããäºå®ã¯å±éºã«èãããŸã
ããšãã°ã次ã®ããã«æžãããšãã§ããŸãã
Property first;
Property second;
<strong i="20">@override</strong>
void initProperties() {
// The state of first depends on second, but second is updated after first
// So we could end up in a bad state, similar to how the build method of a Widget should depend
// on the context.size
first = init(property, MyProperty(second?.value));
second = init(property, Whatever());
}
> class _ExampleSimpleBuilderState extends State<ExampleSimpleBuilder> {
> <strong i="5">@override</strong>
> Widget build(BuildContext context) {
> return TweenAnimationBuilder<double>(
> tween: Tween(begin: 0, end: 1),
> duration: widget.duration1,
> builder: (_, value1, __) {
> return TweenAnimationBuilder<double>(
> tween: Tween(begin: 0, end: 1),
> duration: widget.duration2,
> builder: (_, value2, __) {
> return TweenAnimationBuilder<double>(
> tween: Tween(begin: 0, end: 1),
> duration: widget.duration3,
> builder: (_, value3, __) {
> return Container(
> margin: EdgeInsets.symmetric(vertical: value2 * 20, horizontal: value3 * 30),
> color: Colors.red.withOpacity(value1),
> );
> });
> });
> });
> }
> }
ããã¯ãšãŠãå¥åŠãªäŸã§ãã AnimatedContainerã§ãããå®è¡ã§ããªãã®ã¯ç¢ºãã§ããïŒ
ãã¡ããã ããã§ã®äŸã¯ããXããå®è¡ããããã«ããã€ãã®ãŠã£ãžã§ããã§3ã€ã®ã¢ãã¡ãŒã·ã§ã³ãå©çšããããšã§ãã Xã¯ããã€ã©ãŒãã¬ãŒãã®éã匷調ããããã«ãäŸã§ã¯æå³çã«ç°¡ç¥åãããŠããŸãã
ç§ãããããã©ã®ããã«äœ¿çšããŠãããã«çŠç¹ãåœãŠãªãã§ãã ããã å®éã®äŸã§ã¯ããŠã£ãžã§ããã®ãã³ã¢ãã¯100è¡çšåºŠã§ãããã¢ãã¡ãŒã·ã§ã³åãããããããã£ã¯ããã»ã©åçŽã§ã¯ãªããè€æ°ã®ãã³ãã©ãŒããã®ä»ã®é¢æ°ãå®çŸ©ãããŠããŸãã æé»ã®ãŠã£ãžã§ããã®1ã€ã§åŠçãããªãããšãããŠãããšä»®å®ããŸãïŒAnimatedContainer以å€ã¯éåžžã«åäžç®çã§ãããããé£ããã¯ãããŸããïŒã
éèŠãªã®ã¯ããã®ãããªãã®ãæ§ç¯ããå Žåããã«ããŒã¯æåããèªã¿ãããïŒããã³æžã蟌ã¿å¯èœæ§ïŒã®ç©Žã«ããªããçªãåºããããããŸãæ©èœããªããšããããšã§ãããã®ãããåçŽãªãŠãŒã¹ã±ãŒã¹ã«é©ããŠããããããæ§æããããŸãããè¯ãã 2ã€ä»¥äžã®ãã®ã®æ§æã§ããããšãæ§æããŸãã
ç§ãããããã©ã®ããã«äœ¿çšããŠãããã«çŠç¹ãåœãŠãªãã§ãã ããã å®éã®äŸã§ã¯ã...
...ãããŠæ£æ¹åœ¢ã«æ»ããŸãã ãªãããªãã¯ãå®éã®äŸãæã£ãŠããŸãããïŒ
è€éãªã¢ãã¡ãŒã·ã§ã³ã䜿çšããå®éã®äŸãå¿
èŠã§ããïŒ
https://github.com/gskinnerTeam/flutter_vignettes
ä»»æã®è€éãªã¢ãã¡ãŒã·ã§ã³ã衚瀺ããŠããäŸããããã«ãããªãã ãã§ãã èšããŸã§ããªãããŠã£ãžã§ããå ã§è€æ°ã®ã¢ãã¡ãŒã¿ãŒïŒãŸãã¯æ³åã§ããä»ã®ã¹ããŒããã«ãªããžã§ã¯ãïŒã䜿çšããããã®ãŠãŒã¹ã±ãŒã¹ã¯ãããããããŸã
ãã¡ããã ããã§ã®äŸã¯ããXããå®è¡ããããã«ããã€ãã®ãŠã£ãžã§ããã§3ã€ã®ã¢ãã¡ãŒã·ã§ã³ãå©çšããããšã§ãã Xã¯ããã€ã©ãŒãã¬ãŒãã®éã匷調ããããã«ãäŸã§ã¯æå³çã«ç°¡ç¥åãããŠããŸãã
ãŠã£ãžã§ããã®ãã³ã¢ãã¯100è¡ãäœãã«ãªããŸã
å¥ã®æçš¿ã§ããã³ã¢ããèŠãé ãå®åæã®äŸãæçš¿ããŸããããã³ã¢ã¯æ°çŸè¡ã«ãªããšãã£ããã£ãŠããŸããïŒ ããã§ãå®éã«ã¯ããã€ã©ãŒãã¬ãŒãã¯ã³ã¢ãšæ¯èŒããŠãããããã§ããããïŒ ããªãã¯ãããäž¡æ¹ã®æ¹æ³ã§æã€ããšã¯ã§ããŸããã
ããªãã¯çµ¶ããããªãã®è°è«ãå€ããŠããŸãã
ç§ãããããã©ã®ããã«äœ¿çšããŠãããã«çŠç¹ãåœãŠãªãã§ãã ããã å®éã®äŸã§ã¯ã...
...ãããŠæ£æ¹åœ¢ã«æ»ããŸãã ãªãããªãã¯ãå®éã®äŸãæã£ãŠããŸãããïŒ
ãããããªã¢ã€ãã¢ãããã£ãŠã¿ããšãå®äŸãäœãã®ã«æéããããããã§ãããã ãã®æå³ã¯ãèªè ãå®éã®ç¶æ³ã§ã©ã®ããã«äœ¿çšã§ããããæ³åããããšã§ããããããåé¿ããæ¹æ³ãããããšã¯èšããŸã§ããããŸããã ãã¡ãããã¢ãã¡ãŒã·ã§ã³ã³ã³ããã䜿çšããããšãã§ããŸããã䜿çšã§ããªãå Žåã¯ã©ãã§ããããã ã¢ãã¡ãŒã·ã§ã³åãããã³ã³ããã ãã§äœæããã«ã¯è€éãããå Žåã¯ã©ããªããŸããã
ããŠãäœå®¶ã¯è¯ããæªããã瀺ãããšãã§ããæ¬åœã«å®éã®äŸã䜿çšããŠããªãã®ã§ãç§ã¯ããã«ã€ããŠæèŠã¯ãããŸãããç§ã¯ãã®ã¹ã¬ããã§ããã§ãªãåé¡ã®æ¹åãããããåŸåã«ã€ããŠã³ã¡ã³ãããŠããã ãã§ãæå ã®åé¡ãå®å šã«è§£æ±ºããŸãã ããã¯ãããã¯ã®æ¯æè ãšå察è ã®éã®æ··ä¹±ã®äž»ãªåå ã®ããã§ãããããããããçšåºŠå¥ã®è©±ãããŠããããã«èŠããã®ã§ãå察è ããå®éã®ãäŸã瀺ãããŠããããææ¡è ã¯ãçŸå®äžçã®ã·ããªãªãåã«æ³åããå¿ èŠããããšã¯èšããŸããã
ååãå®åæã§ãã100è¡ã®ã¯ã©ã¹ãæã€ã®ã¯ã°ãããŠãããšç§ã¯èšã£ããšæããŸãã ããã¯ãŸãã«ç§ãããã§èª¬æããŠããããšã§ãã ã³ã¢ã¯ãã©ããªã«å€§ãããŠããå€æ°ã®ãã€ãºã«ãã£ãŠé£èªåãããã¹ãã§ã¯ãããŸãããããã¯ãè€æ°ã®ãã«ããŒã䜿çšããŠããå Žåã«ç¢ºãã«èµ·ãããŸãã
ãã®çç±ã¯ã倧èŠæš¡ãªã³ãŒãããŒã¹å šäœã§ã®ã¹ãã£ã³æ©èœãå¯èªæ§ãããã³ã¡ã³ããã³ã¹ã§ãã ããã¯ç·ã®æžã蟌ã¿ã§ã¯ãããŸãããããã«ããŒã§ã®æžã蟌ã¿ã¯ãäžæ¬åŒ§ã®å°çã«å ¥ãåŸåããããããçç£æ§ã倱ãimoã§ãã
å¥ã®æçš¿ã§ããã³ã¢ããèŠãé ãå®åæã®äŸãæçš¿ããŸããããã³ã¢ã¯æ°çŸè¡ã«ãªããšãã£ããã£ãŠããŸããïŒ ããã§ãå®éã«ã¯ããã€ã©ãŒãã¬ãŒãã¯ã³ã¢ãšæ¯èŒããŠãããããã§ããããïŒ ããªãã¯ãããäž¡æ¹ã®æ¹æ³ã§æã€ããšã¯ã§ããŸããã
ããªãã¯çµ¶ããããªãã®è°è«ãå€ããŠããŸãã
ç¹°ãè¿ããŸããããã®åé¡ã¯å®åæã§ã¯ãªããèªã¿ããããšåå©çšæ§ã«é¢ãããã®ã§ãã
100è¡ã§ãæ§ããŸããã
éèŠãªã®ã¯ããããã®è¡ãã©ãã ãèªã¿åãå¯èœ/ä¿å®å¯èœ/åå©çšå¯èœããšããããšã§ãã
è°è«ãå®åæã«ã€ããŠã§ãã£ããšããŠããåãããšãè¡šçŸããã®ã«ååã«åçã®æ¹æ³ãèãããšããªãç§ããŠãŒã¶ãŒã¯ãã®ãããªå®åæã容èªããå¿ èŠããããŸããïŒ ããã°ã©ãã³ã°ãšã¯ãæœè±¡åãäœæããäœæ¥ãèªååããããšã§ããããŸããŸãªã¯ã©ã¹ããã¡ã€ã«ã§åãããšãäœåºŠãããçŽãæå³ã¯ããŸããããŸããã
è€éãªã¢ãã¡ãŒã·ã§ã³ã䜿çšããå®éã®äŸãå¿ èŠã§ããïŒ
https://github.com/gskinnerTeam/flutter_vignettes
確ãã«ãç§ãããªãã®ãããžã§ã¯ãå šäœãæãäžããããšãæåŸ ããããšã¯ã§ããŸããã ã©ã®ãã¡ã€ã«ãæ£ç¢ºã«èŠãå¿ èŠããããŸããïŒ
ä»»æã®è€éãªã¢ãã¡ãŒã·ã§ã³ã衚瀺ããŠããäŸããããã«ãããªãã ãã§ãã
æ£å察ã§ãã æ¢åã®è§£æ±ºçã§ã¯è§£æ±ºã§ããªãä»»æã®è€éãªã¢ãã¡ãŒã·ã§ã³ã衚瀺ããããšãäŸã§ããããããããã¯ãœã³ãæ±ãç¶ããŠããããšã ãšç§ã¯ä¿¡ããŠããŸãã
gifãã¹ãã£ã³ããŠããã®ãããªãã®ãã©ã®ããã«äœæããããæ³åãå§ããŠãã ããã ãã®ãªããžããªã¯å®éã«ã¯17ã®ã¹ã¿ã³ãã¢ãã³ã¢ããªã§ãã ãŸããè€éãªã¢ãã¡ãŒã·ã§ã³ãååšããå¯èœæ§ãããããšã蚌æããããã ãã«ãç§ãä»»æã®ã¢ãã¡ãŒã·ã§ã³ãäœæããããšãæåŸ ããããšã¯ã§ããŸããã ç§ã¯Flashããå§ããŠ20幎éããããæ§ç¯ããŠããŸããããã©ããååãšã¯ç°ãªããŸãã ãšã«ããã¢ãã¡ãŒã·ã§ã³ã«åºæã®ãã®ã§ã¯ãããŸãããã¢ãã¡ãŒã·ã§ã³ã¯ããã倧ããªãã€ã³ãã説æããããã®æãåçŽã§æã銎æã¿ã®ããAPIã«ãããŸããã
ãåç¥ã®ããã«ãã¢ãã¡ãŒã¿ãŒã䜿çšããå Žåãæ¯å6ã€ã®ããšãè¡ãå¿ èŠããããŸãããã©ã€ããµã€ã¯ã«ããã¯ãå¿ èŠã§ããïŒ ããŠããããæ¯å6ã€ã®ã¹ããããå¿ èŠãªãã®ã«æ¡åŒµããŸã...ãããŠ2ãæã§äœ¿çšããå¿ èŠããããŸãã ãŸãã¯ãäžåºŠã«3ã€äœ¿çšããå¿ èŠããããŸãã ããã¯æããã«åé¡ã§ããä»ã«äœãè¿œå ããŠèª¬æã§ãããããããŸããã
ããã°ã©ãã³ã°ãšã¯ãæœè±¡åãäœæããäœæ¥ãèªååããããšã§ããããŸããŸãªã¯ã©ã¹ããã¡ã€ã«ã§åãããšãäœåºŠãããçŽãæå³ã¯ããŸããããŸããã
__å šãŠ__ïŒ ã§ã¯ãããã©ãŒãã³ã¹ãä¿å®æ§ã¯é¢ä¿ãããŸãããïŒ
åŽåããèªååãããããšãšåŽåããè¡ããããšã¯åãã§ããå ŽåããããŸãã
çãããå®éã®äŸãäœæããæéãåŸåããªããã°åé¡ãããŸããããåé¡ã説æããäŸãäœæããããšã«èå³ããªãå Žåã¯ã人ã ãåé¡ã解決ããããšã匷ããããŠãããšæããŠã¯ãããŸããïŒããã¯ãåé¡ã瀺ãããã®äŸãäœæãããããã¯ããã«å€ãã®äœæ¥ã§ãïŒã ããã§ã¯èª°ã誰ãã®ããã«äœããããå¿ èŠã¯ãããŸãããããã¯ç§ãã¡å šå¡ãäºãã«å©ãåãããšãè©Šã¿ãŠãããªãŒãã³ãœãŒã¹ãããžã§ã¯ãã§ãã
@TimWhiting https://github.com/TimWhiting/local_widget_state_approachesãªããžããªã«ã©ã€ã»ã³ã¹ãã¡ã€ã«ãå ¥ããŠ
åãããšãè¡šçŸããã®ã«ååã«åçã®æ¹æ³ãããå¿ èŠããããŸããïŒ
ã¯ãããã¡ããä¿å®æ§ãšããã©ãŒãã³ã¹ã¯éèŠã§ãã ã€ãŸããåçã®è§£æ±ºçãããå Žåã¯ãå®åæãå°ãªããèªã¿ããããåå©çšãããããã®ãéžæããå¿ èŠããããŸãã ããšãã°ãããã¯ã®ããã©ãŒãã³ã¹ã枬å®ããŠããªãã®ã§ãããã¯ãçãã§ãããšã¯éããŸããããç§ã®çµéšã§ã¯ãããã¯ã®æ¹ãä¿å®ãããããªã£ãŠããŸãã ããã¯ã®ãããªæ§é ãFlutterã³ã¢ã«é 眮ãããå Žåããããããªãã®äœæ¥ã«ã©ã®ããã«åœ±é¿ãããã«ã€ããŠã®ããªãã®è°è«ã«ã€ããŠã¯ãŸã ããããŸããã
gifãã¹ãã£ã³ããŠããã®ãããªãã®ãã©ã®ããã«äœæããããæ³åãå§ããŠãã ããã
gifãã¹ãã£ã³ããŸããã ç§ã¯ãã«ããŒãŠã£ãžã§ããã䜿çšããŸããã
ã¢ãã¡ãŒã·ã§ã³ã®å€ãã¯éåžžã«è€éãªã®ã§ãé«ã¬ãã«ã®ãã«ããŒã䜿çšããŠå®è£
ããããšãããã£ãŠããå Žåã¯ãããããããã±ãŒãžã䜿çšããŸããã
ãšã«ããããã®è°è«ã¯ããå人çãªæèŠã®äžäžèŽã§æã«è² ããªããªã£ãŠããããã§ãã æå ã®äž»ãªã¿ã¹ã¯ã«çŠç¹ãåœãŠãå¿ èŠããããŸãã å ã«è¿°ã¹ãããã«ãæèµ·ãããåé¡ãçã«è§£æ±ºããªãæ¹åãçžæãèŠã€ããå Žåãããã¯ã®æ¯æè ãã©ã®ããã«å°ããªäŸã瀺ãããšãã§ãããã¯ããããŸããã ä»ã®ãšããã @ TimWhitingã®ãªããžããªã«è²¢ç®ããå¿ èŠããããšæããŸãã
æ¢åã®è§£æ±ºçã§ã¯è§£æ±ºã§ããªãä»»æã®è€éãªã¢ãã¡ãŒã·ã§ã³ã衚瀺ããããšãäŸã§ããããããããã¯ãœã³ãæ±ãç¶ããŠããããšã ãšç§ã¯ä¿¡ããŠããŸãã
ä»æ¥äžå¯èœãªããšã®äŸã瀺ãããšã¯ããã®åé¡ã®ç¯å²å€ã§ãã
ãã®åé¡ã¯ãä»æ¥ã¯äžå¯èœãªããã€ãã®ããšã®ãããã¯ã解é€ããã®ã§ã¯ãªãããã§ã«å®çŸå¯èœãªãã®ã®æ§æãæ¹åããããšã«é¢ãããã®ã§ãã
ä»æ¥äžå¯èœãªãã®ãæäŸãããšããèŠæ±ã¯ããããã¯ããå€ããŠããŸãã
@TimWhiting https://github.com/TimWhiting/local_widget_state_approachesãªããžããªã«ã©ã€ã»ã³ã¹ãã¡ã€ã«ãå ¥ããŠ
çµããã ç³ãèš³ãããŸããããäŸã«åãçµãæéãããŸããããŸããã§ããããããããä»é±äžã«ãããå®çŸããã§ãããã
æ¢åã®è§£æ±ºçã§ã¯è§£æ±ºã§ããªãä»»æã®è€éãªã¢ãã¡ãŒã·ã§ã³ã衚瀺ããããšãäŸã§ããããããããã¯ãœã³ãæ±ãç¶ããŠããããšã ãšç§ã¯ä¿¡ããŠããŸãã
ä»æ¥äžå¯èœãªããšã®äŸã瀺ãããšã¯ããã®åé¡ã®ç¯å²å€ã§ãã
ãã®åé¡ã¯ãä»æ¥ã¯äžå¯èœãªããã€ãã®ããšã®ãããã¯ã解é€ããã®ã§ã¯ãªãããã§ã«å®çŸå¯èœãªãã®ã®æ§æãæ¹åããããšã«é¢ãããã®ã§ããä»æ¥äžå¯èœãªãã®ãæäŸãããšããèŠæ±ã¯ããããã¯ããå€ããŠããŸãã
ç§ãèšã£ãããšãèšãæããããŠãã ããã
ã¢ãã¡ãŒã·ã§ã³ãç¶æ ãªã©ãèšè¿°ãããã©ãŒãã³ã¹ã«åœ±é¿ãäžããããšãªãå€§å¹ ã«æ¹åã§ãããä»»æã®è€éãª
ãã€ã©ãŒãã¬ãŒããæžãããåå©çšæ§ãé«ããéæ³ãå¢ããããšã®æšé²ãç解ããŠããŸãã ç§ãã³ãŒããå°ãªãããã®ã奜ãã§ãããå€ãã®äœæ¥ãè¡ãèšèª/ãã¬ãŒã ã¯ãŒã¯ã¯éåžžã«é£æ¬²ãããããŸãã
ãããŸã§ãããã§çŽ¹ä»ããäŸãšãœãªã¥ãŒã·ã§ã³ã®çµã¿åããã¯ã©ãããã³ãŒãã倧å¹
ã«æ¹åãããã®ã§ã¯ãããŸããã§ããã ã€ãŸããäœè¡ã®ã³ãŒããèšè¿°ããªããã°ãªããªããã ãã§ã¯äžååã§ãã
çãããå®éã®äŸãäœæããæéãåŸåããªããã°åé¡ãããŸããããåé¡ã説æããäŸãäœæããããšã«èå³ããªãå Žåã¯ã人ã ãåé¡ã解決ããããšã匷ããããŠãããšæããŠã¯ãããŸããïŒããã¯ãåé¡ã瀺ãããã®äŸãäœæãããããã¯ããã«å€ãã®äœæ¥ã§ãïŒã ããã§ã¯èª°ã誰ãã®ããã«äœããããå¿ èŠã¯ãããŸãããããã¯ç§ãã¡å šå¡ãäºãã«å©ãåãããšãè©Šã¿ãŠãããªãŒãã³ãœãŒã¹ãããžã§ã¯ãã§ãã
@TimWhiting https://github.com/TimWhiting/local_widget_state_approachesãªããžããªã«ã©ã€ã»ã³ã¹ãã¡ã€ã«ãå ¥ããŠ
ãããã®ããŸããŸãªäŸãšã³ãŒãã¹ããããã®äœæã«çŽ6æéãè²»ãããŸããã ããããè€éãªã¢ãã¡ãŒã·ã§ã³ã®å ·äœçãªäŸãæäŸããŠãããããååšã§ããããšã蚌æããã ãã§ã¯ããŸã£ããæå³ããããŸããã
èŠæ±ã¯åºæ¬çã«ãããAnimatedContainerã§åŠçã§ããªããã®ã«å€ããããšã§ãïŒ
Container(margin: EdgeInsets.symmetric(vertical: value2 * 20, horizontal: value3 * 30), color: Colors.red.withOpacity(value1));
ããã¯ãåé¡ã«ã»ãšãã©æå³çã«éæã«ãªããšããç¹ã§éåžžã«äºçŽ°ãªããšã§ãã ããã€ãã®ãã«ã¹ãã¿ã³ãããã€ãã®ç²åã®ç§»åãã¹ã±ãŒãªã³ã°äžã«ãã§ãŒãã€ã³ããããã€ãã®ããã¹ããã£ãŒã«ãããŸãã¯å転ããããã€ãã®ã«ãŒãããããããããªããšæ³åããã®ã¯ãšãŠãé£ããã§ããïŒ 15æ¬ã®ç¬ç«ããããŒãåãããµãŠã³ãããŒãäœæããŠããã®ãããããŸãããã¡ãã¥ãŒãã¹ã©ã€ããããŠããã®ãããããŸããããåã ã®ã¢ã€ãã ãã¹ã©ã€ããããŠæ»ãæ©èœãå¿ èŠã§ãã ãããŠããããŠããããŠããããŠããããŠã ãããŠãããã¯ã¢ãã¡ãŒã·ã§ã³å°çšã§ãã ããã¯ããŠã£ãžã§ããã®ã³ã³ããã¹ãã§ç ©ããããã¹ãŠã®ãŠãŒã¹ã±ãŒã¹ã«é©çšãããŸãã
ç§ã¯ãäž¡æ¹ã®ãã«ããŒãšããã©ç¶æ
ã®åå©çšã«é¢ããåé¡ã®åªããæšæºçãªäŸãæäŸãããšæããŸãã
https://github.com/flutter/flutter/issues/51752#issuecomment -671566814
https://github.com/flutter/flutter/issues/51752#issuecomment -671489384
ãããã®ã€ã³ã¹ã¿ã³ã¹ã®å€ããæ³åããã ãã§ïŒæ¯ãéžã¶ïŒã1000以äžã®ã¯ã©ã¹ãã¡ã€ã«ã®ãããžã§ã¯ãå šäœã«åºç¯å²ã«åºãããåé¿ããããšããŠããå¯èªæ§ãšä¿å®æ§ã®åé¡ãå®å šã«ææ¡ã§ããŸãã
@esDotDevãæäŸãããµã³ãã«ç»åã¯ããã¹ãã«ãã£ãŠã³ãŒããèªã¿ã«ãããªãã @ Rudikszã«ãšã£ãŠååã§ã¯ãªãããšã@ rrousselGitã¯ãã«ããŒãããããã©ãŒãã³ã¹ã
@esDotDevéèŠãªã®ã¯ããã¹ãŠã®ã©ã€ããµã€ã¯ã«ç®¡çãœãªã¥ãŒã·ã§ã³ãæ¯èŒã§ããåäžã®æšæºçãªäŸã
ããã¯ç§ã«ã¯çã«ããªã£ãŠããŸããããªããããåäžã®ããŒãžããã倧ãããªããã°ãªããªãã®ãç解ã§ããŸããã
è€æ°ã®ã¢ãã¡ãŒã·ã§ã³ã管çããããšã¯ãäžè¬çã§ã倧éã®å®åæãå¿ èŠãšãããšã©ãŒãçºçãããããçŸåšãé©åãªè§£æ±ºçããªãããšã®å®ç§ãªäŸã§ãã ãããæå³ããªããªãå Žåãã¢ãã¡ãŒã·ã§ã³ãã©ã®ããã«è€éã«ãªããããç解ããŠããªããšäººã ãèšããªããæããã«ãã¢ãŒããã¯ãã£ã®åé¡ã§ã¯ãªãããŠãŒã¹ã±ãŒã¹ã®ã³ã³ããã¹ãã®ããã«ãã¹ãŠã®ãŠãŒã¹ã±ãŒã¹ãããã¯ããŠã³ãããŸã説æããããšããŠããŸãã
確ãã«ã@ TimWhitingã®ãªããžããªã«ã¯æ¬æ Œçãªã¢ããªã¯ãããŸãããããªããèšãããã«ãäŸãšããŠåäžã®ããŒãžããããŸããä»ã®äººããœãªã¥ãŒã·ã§ã³ãå®è£ ã§ãããªããžããªã®ã¢ãã¡ãŒã·ã§ã³ã®æšæºçãªäŸãäœæã§ããã°ãããã¯æ©èœããŸãã
ãŸãã巚倧ãªã¢ããªãªã©ã¯å¿ èŠãªããšæããŸãããTodoMVCãšåæ§ã«ååãªè€éããå¿ èŠã§ãã åºæ¬çã«ã¯ã察æŠçžæãããããªé¢šã«ãã£ãšäžæããããããšèšããªãçšåºŠã«ååã§ããå¿ èŠããããŸãã
@Hixieã¢ãããŒããæ¯èŒããããã®å®éã®ã¢ããªã®ãªã¯ãšã¹ãã«ã¯æ¬ é¥ããããŸãã
2ã€ã®æ¬ é¥ããããŸãïŒ
ããšãã°ã次ã䜿çšããŠã¢ããªã±ãŒã·ã§ã³ãäœæããããšã¯ã§ããŸããã
final snapshot = keyword StreamBuilder();
ããã¯å®è£ ãããŠããªãããã§ãã
ããã¯POCãšæ¬çªã³ãŒããæ¯èŒããŠãããããããã©ãŒãã³ã¹ãå€æããããšãã§ããŸããã
誀çšããã£ããšãã«ãšã©ãŒãææããã³ã³ãã€ã©çµ±åããªãããããããã¯ãæ¡ä»¶ä»ãã§åŒã³åºãããšãã§ããªãããªã©ã®ãããªãã®ããšã©ãŒãèµ·ããããããã©ãããè©äŸ¡ããããšã¯ã§ããŸããã
èšèšã®ããã©ãŒãã³ã¹ã®å€æãAPIã®äœ¿ããããã®è©äŸ¡ãå®è£ åã®å®è£ ...ãããã¯ãã¹ãŠAPIèšèšã®äžéšã§ãã ç§ã®ä»äºãžããããã ïŒ-ïŒïŒãã©ãã¿ãŒããªãã¢ïŒdartïŒuiãäœæããåã«ãRenderObjectãšRenderBoxãªã©ã®æåã®æ°åè¡ãå®è£ ãããŠããããšããåç¥ã§ããïŒïŒ
ããã¯ããªããäžå¯èœãèŠæ±ããŠãããšããäºå®ãå€ããŸããã
ããã§è¡ãããææ¡ã®äžéšã¯ãèšèªãŸãã¯ã¢ãã©ã€ã¶ãŒã®äžéšã§ãã ã³ãã¥ããã£ããããå®è£ ããããšã¯äžå¯èœã§ãã
ä»ã®ãã¬ãŒã ã¯ãŒã¯ãèšèªãåžžã«APIèšèšãè¡ã£ãŠãããã©ããã¯ããããŸãããããã§ã¯ããã»ã©éãã¯ãªããšæããŸãããŸããFlutterã«ã¯ä»ã®èšèªãšã®APIèšèšã®å€§ããªéããé£ããããããŸãã ã®ããã«ãã³ã³ãã€ã©ãã¢ãã©ã€ã¶ã®ãµããŒããªãã§ãããè¡ããŸãããããã¯æŠå¿µå®èšŒã«ãããŸããã
3ã€ã®ã¢ãã¡ãŒã·ã§ã³ãããŸãå©çšãããã€ã©ãŒãã¬ãŒããšã¯ã©ãããããªãããŒãããããè€éãªãã¢ãã¡ãŒã·ã§ã³ã·ããªãªã®äŸããŸãšããŸããã
éå§äœçœ®ãžã®ããŒãã¹ãããããã¯ïŒãã¹ãŠã®æé»ã®ãŠã£ãžã§ãããåé€ïŒãz軞ã§ã®å転ãåäžè»žã§ã®ã¹ã±ãŒã«ããŸãã¯IWã§ã«ããŒãããŠããªããã®ä»ã®ãŠãŒã¹ã±ãŒã¹ãå¿ èŠãšããã¢ãã¡ãŒã·ã§ã³ãå®è¡ã§ããå¯èœæ§ãããããšã«æ³šæããŠãã ããã ããããçå£ã«åãæ¢ããããªãã®ã§ã¯ãªãããšå¿é ããã®ã§ïŒç§ã®ãã¶ã€ããŒã¯äžæ¥äžãã®ãããªãã®ãç§ã«æž¡ããŠãããŸããïŒãç§ã¯ãã£ãšãçŸå®ã®äžçããäœããŸããã
ãããåçŽãªè¶³å Žã§ããã¹ã©ã€ãããŠééãã3ã€ã®ããã«ããããŸãã é¢æ£ç¶æ
ã®3ã€ã®ã¢ãã¡ãŒã¿ãŒã䜿çšããŸãã ãã®å ŽåãAnimatorControllerã®å®å
šãªå¶åŸ¡ã¯å®éã«ã¯å¿
èŠãããŸãããTweenAnimationBuilderã¯åé¡ãããŸããããçµæãšããŠããªãŒã«ãã¹ããããããšã¯éåžžã«æãŸãããããŸããã ããã«ã¯çžäºã®å€ã«äŸåããŠãããããTABãããªãŒã®äžã«ãã¹ãããããšã¯ã§ããŸããã AnimatedContainerã¯ãåããã«ãç»é¢ããã¹ã©ã€ãããå¿
èŠããããããããã§ã¯ãªãã·ã§ã³ã§ã¯ãããŸããããã¹ããã·ã¥ãããŸããã
https://i.imgur.com/BW6M3uM.gif
class _SlidingPanelViewState extends State<SlidingPanelView> with TickerProviderStateMixin {
AnimationController leftMenuAnim;
AnimationController btmMenuAnim;
AnimationController rightMenuAnim;
<strong i="12">@override</strong>
void initState() {
// Here I have to pass vsync to AnimationController, so I have to include a SingleTickerProviderMixin and somewhat magically pass 'this' as vsync.
leftMenuAnim = AnimationController(duration: widget.slideDuration, vsync: this);
btmMenuAnim = AnimationController(duration: widget.slideDuration, vsync: this);
rightMenuAnim = AnimationController(duration: widget.slideDuration, vsync: this);
// Here I have to call forward 3 times, cause there's no way to automate this common setup behavior
leftMenuAnim.forward();
btmMenuAnim.forward();
rightMenuAnim.forward();
// Here I have to manually bind to build, cause there is encapsulate this common setup behavior
leftMenuAnim.addListener(() => setState(() {}));
btmMenuAnim.addListener(() => setState(() {}));
rightMenuAnim.addListener(() => setState(() {}));
super.initState();
}
// Following 2 fxn are a blind spot as far as compiler is concerned.
// Things may, or may not be implemented correctly, no warnings, no errors.
<strong i="13">@override</strong>
void dispose() {
btmMenuAnim.dispose();
leftMenuAnim.dispose();
rightMenuAnim.dispose();
super.dispose();
}
<strong i="14">@override</strong>
void didUpdateWidget(SlidingPanelView oldWidget) {
if (leftMenuAnim.duration != widget.slideDuration) {
leftMenuAnim.duration = widget.slideDuration;
btmMenuAnim.duration = widget.slideDuration;
rightMenuAnim.duration = widget.slideDuration;
}
super.didUpdateWidget(oldWidget);
}
// End error-prone blind spot without a single line of unique code
// ~50 lines in we can start to see some unique code
void _toggleMenu(AnimationController anim) {
bool isOpen = anim.status == AnimationStatus.forward || anim.value == 1;
isOpen ? anim.reverse() : anim.forward();
}
<strong i="15">@override</strong>
Widget build(BuildContext context) {
double leftPanelSize = 320;
double leftPanelPos = -leftPanelSize * (1 - leftMenuAnim.value);
double rightPanelSize = 230;
double rightPanelPos = -rightPanelSize * (1 - rightMenuAnim.value);
double bottomPanelSize = 80;
double bottomPanelPos = -bottomPanelSize * (1 - btmMenuAnim.value);
return Stack(
children: [
//Bg
Container(color: Colors.white),
//Content Panel
Positioned(
top: 0,
left: leftPanelPos + leftPanelSize,
bottom: bottomPanelPos + bottomPanelSize,
right: rightPanelPos + rightPanelSize,
child: ChannelInfoView(),
),
//Left Panel
Positioned(
top: 0,
left: leftPanelPos,
bottom: bottomPanelPos + bottomPanelSize,
width: leftPanelSize,
child: ChannelMenu(),
),
//Bottom Panel
Positioned(
left: 0,
right: 0,
bottom: bottomPanelPos,
height: bottomPanelSize,
child: NotificationsBar(),
),
//Right Panel
Positioned(
top: 0,
right: rightPanelPos,
bottom: bottomPanelPos + bottomPanelSize,
width: rightPanelSize,
child: SettingsMenu(),
),
// Buttons
Row(
children: [
Button("left", ()=>_toggleMenu(leftMenuAnim)),
Button("btm", ()=>_toggleMenu(btmMenuAnim)),
Button("right", ()=>_toggleMenu(rightMenuAnim)),
],
)
],
);
}
}
//Demo helpers
Widget Button(String lbl, VoidCallback action) => FlatButton(child: Text(lbl), onPressed: action, color: Colors.grey);
Widget ChannelInfoView() => _buildPanel(Colors.red);
Widget ChannelMenu() => _buildPanel(Colors.pink);
Widget SettingsMenu() => _buildPanel(Colors.blue);
Widget NotificationsBar() => _buildPanel(Colors.grey);
Widget _buildPanel(Color c) => Container(color: c, child: Container(color: Colors.white.withOpacity(.5)), padding: EdgeInsets.all(10));
ãããã£ãŠããã®æ¬äœã®100è¡çšåºŠã®ãã¡ãçŽ40ïŒ ãçŽç²ãªå®åæã§ãã ç¹ã«15è¡ã¯ãæ¬ èœããŠãããã®ãå ¥åãã¹ããããšãèŠã€ãã«ãããã°ãåŒãèµ·ããå¯èœæ§ããããŸãã
StatefulPropertyã®ãããªãã®ã䜿çšãããšããã€ã©ãŒãã¬ãŒãã15ïŒ çšåºŠã«åæžãããŸãïŒçŽ25è¡ç¯çŽã§ããŸãïŒã éèŠãªããšã«ãããã¯åå£ãªãã°ãšéè€ããããžãã¹ããžãã¯ã®åé¡ãå®å šã«è§£æ±ºããŸãããç¹ã«StatefulWidgetãå¿ èŠãªããããŸã å°ãåé·ã§ããããã¯ãããã«10è¡ãããããŸãã
'keyword'ã®ãããªãã®ã䜿çšããå Žåãå®åæã®è¡ãåºæ¬çã«0ïŒ ã«æžãããŸãã ã¯ã©ã¹ã®å šäœã®çŠç¹ã¯ãïŒäžæã®ïŒããžãã¹ããžãã¯ãšããžã¥ã¢ã«ããªãŒèŠçŽ ã«ããå¯èœæ§ããããŸãã äžè¬ã«ãStatefulWIdgetsã®äœ¿çšã¯ã¯ããã«ãŸãã«ãªãããã¥ãŒã®å€§éšåã¯10ïŒ ãŸãã¯20ïŒ å°ãªããªããããçŠç¹ãçµãããŸãã
ãŸããäžèšã®Panelã·ããªãªã¯çŸå®ã®äžçã§ãããçŸå®ã®äžçã§ã¯æããã«ãã®ã¢ãããŒãã¯ããŸãè¯ããªãããã䜿çšããŸããã§ãããã³ãŒãããŒã¹ã«ã¯è¡šç€ºãããŸããã ãŸãããã¹ãããããã«ããŒã䜿çšããªãã®ã§ãããããç²ãèŠããã®ã§ãããã衚瀺ãããŸããã
IsOpenããããã£ãååŸããããèªäœãéãããéãããããå°çšã®SlidingPanelãŠã£ãžã§ãããäœæããŸããã ããã¯éåžžãç¹å®ã®åäœãå¿ èŠãªãããã®ãŠãŒã¹ã±ãŒã¹ã®ãã¹ãŠã®ãœãªã¥ãŒã·ã§ã³ã§ãããã¹ããŒããã«ããžãã¯ãç¹å®ã®ãŠã£ãžã§ããã«ç§»åããããã䜿çšããŸãã åºæ¬çã«ãç¬èªã®ImplicitlyAnimatedWidgetãäœæããŸãã
ããã¯éåžžã¯åé¡ãªãæ©èœããŸãããããã§ãæéãšåŽåãããããŸããæåéããã¢ãã¡ãŒã·ã§ã³ã䜿çšããã®ãéåžžã«é£ããããã§ãïŒã¹ããŒããã«ã³ã³ããŒãã³ããåå©çšããã®ã¯äžè¬çã«éåžžã«é£ããããã§ãïŒã ããšãã°ãUnityãAIRã§ã¯ãããã«ã1ã€ã®è»žäžã§ç§»åããããã ãã«å°çšã®ã¯ã©ã¹ãäœæããã®ã§ã¯ãªããéãããéãããããã®ã¯1è¡ã®ã³ãŒãã§ãããå°çšã®ãŠã£ãžã§ããã§è¡ãããšã¯äœããããŸããã Flutterã§ã¯ãå°çšã®ãŠã£ãžã§ãããäœæããå¿ èŠããããŸããããã¯ãAnimatorControllerã®ããŒãã¹ãã©ãããšãã£ã¢ããŠã³ãã«ãã»ã«åããããã®æåéãå¯äžã®åççãªæ¹æ³ã§ãïŒTABã§ãã¹ãããã¹ãããã¹ãããå Žåãé€ãïŒ
ããã§ã®ç§ã®äž»ãªãã€ã³ãã¯ããã®çš®ã®ããšã¯ãå®éã®äŸãèŠã€ããã®ãéåžžã«é£ããçç±ã§ãã éçºè ãšããŠããããã®ãã®ãã³ãŒãããŒã¹ã«ããŸãååšãããããšã¯ã§ããªããããçæ³çã§ã¯ãããŸãããå¹æçãªåé¿çã§åé¿ããŸãã 次ã«ãã³ãŒãããŒã¹ãèŠããšããããã®åé¿çãæå¹ã«ãªã£ãŠããããšããããããã¹ãŠãæ£åžžã«èŠããŸãããããŒã ãæãã§ãããã®ã§ã¯ãªãå¯èœæ§ããããããã«å°éãããŸã§ã«20ïŒ é·ãããã£ãå¯èœæ§ããããåèšã§ãã£ãå¯èœæ§ããããŸããããã°ããã®ãé¢åã§ãããã³ãŒããäžç¥ããã ãã§ã¯æããã§ã¯ãããŸããã
å®å šãæãããã«ãããã¯ãã«ããŒã§äœæãããåããŠãŒã¹ã±ãŒã¹ã§ãã è¡æ°ãå€§å¹ ã«åæžããããã°ã®å¯èœæ§ããªããå€åœã®æŠå¿µRE TickerProviderMixinãåŠã¶å¿ èŠããããŸãã...ãããããã®å ¥ãåã¯æ²ãã¿ã§ãããããŸããŸãªå€æ°ãããªãŒå šäœã«æ£ãã°ãæ¹æ³ïŒåççµäºå€ãå€1ãå€2ãªã©ïŒ ïŒããžãã¹ããžãã¯ãå¿ èŠä»¥äžã«èªã¿ã«ãããªããŸãã
`` `ããŒã
ã¯ã©ã¹_SlidingPanelViewStateã¯Stateãæ¡åŒµããŸã
bool isLeftMenuOpen = true;
bool isRightMenuOpen = true;
bool isBtmMenuOpen = true;
@ãªãŒããŒã©ã€ã
ãŠã£ãžã§ãããã«ãïŒBuildContextã³ã³ããã¹ãïŒ{
TweenAnimationBuilderãè¿ã
ãã¥ã€ãŒã³ïŒãã¥ã€ãŒã³ïŒéå§ïŒ0ãçµäºïŒisLeftMenuOpenïŒ1ïŒ0ïŒã
æéïŒwidget.slideDurationã
ãã«ããŒïŒïŒ_ãleftAnimValueã__ïŒ{
TweenAnimationBuilderãè¿ã
ãã¥ã€ãŒã³ïŒãã¥ã€ãŒã³ïŒéå§ïŒ0ãçµäºïŒisRightMenuOpenïŒ1ïŒ0ïŒã
æéïŒwidget.slideDurationã
ãã«ããŒïŒïŒ_ãrightAnimValueã__ïŒ{
TweenAnimationBuilderãè¿ã
ãã¥ã€ãŒã³ïŒãã¥ã€ãŒã³ïŒéå§ïŒ0ãçµäºïŒisBtmMenuOpenïŒ1ïŒ0ïŒã
æéïŒwidget.slideDurationã
ãã«ããŒïŒïŒ_ãbtmAnimValueã__ïŒ{
double leftPanelSize = 320;
double leftPanelPos = -leftPanelSize *ïŒ1-leftAnimValueïŒ;
double rightPanelSize = 230;
double rightPanelPos = -rightPanelSize *ïŒ1-rightAnimValueïŒ;
double bottomPanelSize = 80;
double bottomPanelPos = -bottomPanelSize *ïŒ1-btmAnimValueïŒ;
ã¹ã¿ãã¯ãè¿ã
åäŸéïŒ [
// Bg
ã³ã³ããïŒè²ïŒColors.whiteïŒã
//ã¡ã€ã³ã³ã³ãã³ããšãªã¢
ããžã·ã§ãã³ã°ïŒ
äžïŒ0ã
å·ŠïŒleftPanelPos + leftPanelSizeã
äžïŒbottomPanelPos + bottomPanelSizeã
å³ïŒrightPanelPos + rightPanelSizeã
åïŒChannelInfoViewïŒïŒã
ïŒã
//å·Šããã«
ããžã·ã§ãã³ã°ïŒ
äžïŒ0ã
å·ŠïŒleftPanelPosã
äžïŒbottomPanelPos + bottomPanelSizeã
å¹
ïŒleftPanelSizeã
åïŒChannelMenuïŒïŒã
ïŒã
//äžéšããã«
ããžã·ã§ãã³ã°ïŒ
å·ŠïŒ0ã
å³ïŒ0ã
äžïŒbottomPanelPosã
é«ãïŒbottomPanelSizeã
åïŒNotificationsBarïŒïŒã
ïŒã
//å³ããã«
ããžã·ã§ãã³ã°ïŒ
äžïŒ0ã
å³ïŒrightPanelPosã
äžïŒbottomPanelPos + bottomPanelSizeã
å¹
ïŒrightPanelSizeã
åïŒSettingsMenuïŒïŒã
ïŒã
//ãã¿ã³
è¡ïŒ
åäŸéïŒ [
ButtonïŒ "left"ãïŒïŒ=> setStateïŒïŒïŒ=> isLeftMenuOpen =ïŒisLeftMenuOpenïŒïŒã
ButtonïŒ "btm"ãïŒïŒ=> setStateïŒïŒïŒ=> isBtmMenuOpen =ïŒisBtmMenuOpenïŒïŒã
ButtonïŒ "right"ãïŒïŒ=> setStateïŒïŒïŒ=> isRightMenuOpen =ïŒisRightMenuOpenïŒïŒã
]ã
ïŒ
]ã
ïŒ;
}ã
ïŒ;
}ã
ïŒ;
}ã
ïŒ;
}
}
æåŸã®1ã€ã¯èå³æ·±ãã§ã...ç§ã¯åœåããã«ããŒãã¹ã¿ãã¯ã§ã¯ãªãé
眮ãŠã£ãžã§ããã®åšãã«ããã¹ãã§ããããšãææ¡ããããšããŠããŸããïŒãããŠç§ã¯ãŸã å·Šãšå³ã®ããã«ã®ããã«ãããææ¡ããŸãïŒããããããç§ã¯äžçªäžã®ãã®ã圱é¿ããããšã«æ°ã¥ããŸãã3ã€ãã¹ãŠã§ã Container
ãšRow
äž¡æ¹ãäžå®ã«ä¿ã¡ããã®ã§ããã«ããŒãchild
åŒæ°ã1ã€ã ãäžããã ãã§ã¯å®éã«ã¯ååã§ã¯ãªãããšã«æ°ä»ããŸããããã«ãããŸãã æåã®ãã«ããŒã®äžã«äœæã§ãããšæããŸãã
ããã§ã®ç§ã®äž»ãªãã€ã³ãã¯ããã®çš®ã®ããšã¯ãå®éã®äŸãèŠã€ããã®ãéåžžã«é£ããçç±ã§ãã éçºè ãšããŠããããã®ãã®ãã³ãŒãããŒã¹ã«ããŸãååšãããããšã¯ã§ããªããããçæ³çã§ã¯ãããŸãããå¹æçãªåé¿çã§åé¿ããŸãã 次ã«ãã³ãŒãããŒã¹ãèŠããšããããã®åé¿çãæå¹ã«ãªã£ãŠããããšããããããã¹ãŠãæ£åžžã«èŠããŸãããããŒã ãæãã§ãããã®ã§ã¯ãªãå¯èœæ§ããããããã«å°éãããŸã§ã«20ïŒ é·ãããã£ãå¯èœæ§ããããåèšã§ãã£ãå¯èœæ§ããããŸããããã°ããã®ãé¢åã§ãããã³ãŒããäžç¥ããã ãã§ã¯æããã§ã¯ãããŸããã
èšé²ãšããŠãããã¯å¶ç¶ã§ã¯ãããŸããã ããã¯éåžžã«ä»æ§ã«ãããã®ã§ãã ãããã®ãŠã£ãžã§ãããç¬èªã®ãŠã£ãžã§ããã«ããããšã§ãããã©ãŒãã³ã¹ãåäžããŸãã ç§ãã¡ã¯ãããã人ã ãFlutterãã©ã®ããã«äœ¿çšããããšããããšãéåžžã«æå³ããŠããŸããã ããã¯ããFlutterã®èšèšå²åŠã®å€§éšåã¯ã人ã ãæ£ããéžæã«å°ãããšã§ãããšè¿°ã¹ããšãã«ç§ãäžã§èšåãããã®ã§ãã
ç§ã¯åœåããã«ããŒãã¹ã¿ãã¯ã§ã¯ãªããPositionedãŠã£ãžã§ããã®åšãã«ããã¹ãã ãšææ¡ããããšããŠããŸããïŒãããŠãå·Šå³ã®ããã«ã«ã€ããŠãææ¡ããŸãïŒ
ç°¡æœã«ããããã«å®éã«ã¯çç¥ããŸããããéåžžã¯ããã«Contentã³ã³ãããŒãå¿ èŠã§ããã3ã€ã®ã¡ãã¥ãŒãã¹ãŠã®ãµã€ãºã䜿çšããŠç¬èªã®äœçœ®ãå®çŸ©ããŸãã ã€ãŸãã3ã€ãã¹ãŠãããªãŒã®æäžäœã«ããå¿ èŠããããåæ§ç¯ããå Žåã¯ããã¥ãŒå šäœãåæ§ç¯ããå¿ èŠããããåé¿ããå¿ èŠã¯ãããŸããã ããã¯åºæ¬çã«ããªãã®å€å žçãªãã¹ã¯ãããã¹ã¿ã€ã«ã®è¶³å Žã§ãã
ãã¡ãããããªãŒãå解ãå§ããããšãã§ããŸããåžžã«ãªãã·ã§ã³ã§ãã倧ããªãŠã£ãžã§ããã«ãã䜿çšããŸãããå®éã«äžç®ã§ã°ããŒã«ããªãã£ãåäžããããšã¯äžåºŠãèŠãããšããããŸãããèªè ããããè¡ãããã«å¿ èŠãªè¿œå ã®èªç¥ã¹ãããããããŸããç¹ã ããªããæšããã©ãã©ã«ããç¬éãç§ã¯çªç¶ãå€æ°ã®å²ãåœãŠã®ãã³ããã®è·¡ããã©ã£ãŠãããã§äœãæž¡ãããŠããã®ãããããŠå šäœãã©ã®ããã«çµã¿åããããŠããã®ããç解ããŸããã æ¶åå¯èœãªæšãšããŠæšãæ瀺ããããšã¯ãç§ã®çµéšããåžžã«æšè«ããã®ãç°¡åã§ãã
ãããããå°çšã®RenderObjectã®è¯ããŠãŒã¹ã±ãŒã¹ã§ãã
ãŸãã¯ããŠã£ãžã§ããã®ã©ã€ããµã€ã¯ã«ã«èªåèªèº«ãããã¯ã§ãã3ã€ã®ç°¡åã«ç®¡çã§ããAnimatorObjectsïŒD
ãããã®ãŠã£ãžã§ãããç¬èªã®ãŠã£ãžã§ããã«ããããšã§ãããã©ãŒãã³ã¹ãåäžããŸãã
ããã§å ·äœçã«èª¬æããŸãããã®å Žåãããã¯è¶³å Žã§ããããããã¹ãŠã®ãµããã¥ãŒã¯ãã§ã«ç¬èªã®ãŠã£ãžã§ããã«ãªã£ãŠããŸãããã®ç·ã¯ãåã®ã¬ã€ã¢ãŠããšç¿»èš³ãæ åœããŸãã åã¯BottomMenuïŒïŒãChannelMenuïŒïŒãSettingsViewïŒïŒãMainContentïŒïŒãªã©ã«ãªããŸã
ãã®å Žåãèªå·±å®çµåãŠã£ãžã§ããã®æããèªå·±å®çµåãŠã£ãžã§ããã®å¥ã®ã¬ã€ã€ãŒã§ã©ããããŠããŠã£ãžã§ããã®ç§»åã«é¢ããå®åæã管çããŸãã ãããããã©ãŒãã³ã¹ã®åå©ã ãšã¯æããŸãããïŒ ãã®å Žåãç§ãã¡ã¯ããã¬ãŒã ã¯ãŒã¯ãå®éã«ããããããšã§ã¯ãªããç§ãã¡ãããããããšã_èããŠãã_ããšã«æŒã蟌ãŸããŠããŸããããã¯ãããç°¡æœã§éŠå°Ÿäžè²«ããæ¹æ³ã§åçã®ããã©ãŒãã³ã¹ã®ãã¥ãŒãæžãããšã§ãã
[ç·šé]ãã®ã³ã³ããã¹ããè¿œå ããããã«äŸãæŽæ°ããŸã
å°çšã®RenderObjectãææ¡ããçç±ã¯ãã¬ã€ã¢ãŠããæ¹åãããããã§ãã ã¢ãã¡ãŒã·ã§ã³ã®åŽé¢ãã¹ããŒããã«ãŠã£ãžã§ããã«ããããšã«åæããŸããã¹ã¿ãã¯èšç®ãè¡ã代ããã«ã3ã€ã®0..1ããã«ïŒvalue1ãvalue2ãvalue3ïŒãã¬ã³ããŒãªããžã§ã¯ãã«æž¡ãã ãã§ãã ããããããã¯äž»ã«ãã®è°è«ã®ãµã€ãã·ã§ãŒã§ãã ãããå®è¡ããŠããæç¹ã§ããããã¯ãªã©ã®ã¹ããŒããã«ãŠã£ãžã§ããã§æäŸãããåçŽåãå®è¡ããå¿ èŠããããŸãã
ããé¢é£æ§ã®é«ãã¡ã¢ãšããŠã @ TimWhitingã®ãããžã§ã¯ãã®ãã¢ãäœæããéã«äºè£ããããŸããïŒ https ïŒ
ããã¯ããŒãžã§ã³ãã©ã®ããã«ãªãã®ãèå³ããããŸãã ç¹ã«ããã©ãŒãã³ã¹ç¹æ§ãç¶æããïŒãŸãã¯ããããæ¹åãããçŸåšæé©ã§ã¯ãªãå Žæã瀺ãã³ã¡ã³ãããããŸãïŒããããåçŽåããããã®è¯ãæ¹æ³ãèŠã€ããããšãã§ãããã©ããã¯ããããŸããã
ïŒããããåçŽåããæ¹æ³ãèŠã€ããå Žåã«ããã§å®è¡ããããããªãã®ãªã®ãããããšãå®äºããåã«è§£æ±ºããå¿ èŠã®ããéèŠãªããšãæ¬ èœããŠããã®ããéåžžã«èå³ããããŸããïŒ
ãã®äŸã§ã¯ã埩å ãéèŠã§ããïŒ ãã®ããã§ãã©ããŒããã®ã«èŠåŽããŠããŠãRestorationMixinãäœãããŠããã®ãæ¬åœã«ããããŸããã ç§ã¯ããã...ç§ã®ããã«ãããç解ããã®ã«å°ãæéããããã ãããšæããŸãã ã¬ãã¯4ç§ã§ããã¯ããŒãžã§ã³ãã¯ã©ã³ã¯ã¢ãŠããããšç¢ºä¿¡ããŠããŸã:)
䜿çšããŠåŸ©å
APIã䜿çšããŠHookWidget
ã§ã¯ãªãStatefulHookWidget
çŸæç¹ã§ã¯ãµããŒããããŠããŸããã
çæ³çã«ã¯ç§ãã¡ã¯å€ããããšãã§ããã¯ãã§ã
final value = useState(42);
ã®äžãžïŒ
final value = useRestorableInt(42);
ãã ããçŸåšã®åŸ©å APIã¯å®éã«ã¯ããã¯ã念é ã«çœ®ããŠèšèšãããŠããªããããããçšåºŠã®èæ ®ãå¿ èŠã§ãã
è£è¶³ãšããŠãReactããã¯ã«ã¯ãããŒãæ©èœãä»å±ããŠãããéåžžã¯æ¬¡ã®ããã«äœ¿çšãããŸãã
int userId;
Future<User> user = useMemo(() => fetchUser(id), [id]);
ãã®ã³ãŒãã¯ããã³ãŒã«ããã¯ã®çµæããã£ãã·ã¥ããé åå ã®äœããå€æŽããããã³ã«ã³ãŒã«ããã¯ãåè©äŸ¡ãããããšãæå³ããŸãã
Flutter_hooksã¯ããã1察1ã§åå®è£ ããŸããïŒããã¯åãªãããŒãã§ããããïŒããFlutterã«æé©åãããã³ãŒãã«å¯ŸããŠãããå®è¡ããããšã¯æããŸããã
ç§ãã¡ã¯ãããã欲ããã§ãããïŒ
int userId;
Future<User> user = useMemo1(id, (id) => fetchUser(id));
ããã¯åãããšãããŸããããªã¹ãã®å²ãåœãŠãé¿ããé¢æ°ã®ãã£ã¢ãªãã䜿çšããããšã§ã¡ã¢ãªã®è² è·ãåãé€ããŸã
ãã®æ®µéã§ã¯éèŠã§ã¯ãããŸããããäŸãšããŠflutter_hooks
ã䜿çšããäºå®ãããå Žåã¯èšåãã䟡å€ããããŸãã
@Hixieã¢ãã¡ãŒã·ã§ã³ã®äŸãããã¯ã«ç§»æ€ããŸãã
ããã¯èå³æ·±ãäŸã§ãããããã«ã€ããŠèããããšã«å¯Ÿãã称è³ã§ãïŒ
ããã¯ãããã©ã«ãã§ãã¢ã¯ãã£ãããšãæéãã®å®è£
ãããããšããã«ããïŒãããŠçžäºã«äŸåããŠããïŒãšããç¹ã§è¯ãäŸã§ãã
ãã€ã³ããŸã§ãå€æ°ã®ãifïŒã¢ã¯ãã£ãïŒã/ãcontroller.repeatãåŒã³åºãããããŸãã
äžæ¹ãããã¯ã䜿çšãããšããã¹ãŠã®ããžãã¯ã宣èšçã«åŠçãããéè€ããããšãªã1ãæã«éäžããŸãã
ãã®äŸã§ã¯ãããã¯ã䜿çšããŠãªããžã§ã¯ããç°¡åã«ãã£ãã·ã¥ããæ¹æ³ã瀺ããŠããŸããããã«ãããExpensiveWidgetã®åæ§ç¯ãé »ç¹ã«çºçããåé¡ãä¿®æ£ãããŸããã
constã³ã³ã¹ãã©ã¯ã¿ãŒã®å©ç¹ã¯ãããŸãããåçãã©ã¡ãŒã¿ãŒã§æ©èœããŸãã
ãŸããããåªããããããªããŒããåŸãããŸãã èæ¯è²ã®Timer.periodicæéãå€æŽãããšãå€æŽã®å¹æãããã«ç¢ºèªã§ããŸãã
@rrousselGitãªã³ã¯ã¯ãããŸããïŒ @TimWhitingã®ãªããžããªã«æ°ãããã®ã¯äœããããŸããã§ããã
䜿çšããŠåŸ©å APIã䜿çšããŠ
HookWidget
ã§ã¯ãªãStatefulHookWidget
çŸæç¹ã§ã¯ãµããŒããããŠããŸããã
ã©ããªè§£æ±ºçãæãã€ãããšããŠããæåŸã®ãã¹ãŠã®ããã¯ã¹ã€ã³ã«ã€ããŠç¥ãå¿ èŠããªãããšã確èªããå¿ èŠããããŸãã TickerProviderStateMixinãRestorationMixinã®ãããªããã¯ã¹ã€ã³ãå°å ¥ããä»ã®ããã±ãŒãžãšçµã¿åãããŠç§ãã¡ã®ãœãªã¥ãŒã·ã§ã³ã䜿çšãããå Žåã¯ãããããããšãã§ããã¯ãã§ãã
https://github.com/TimWhiting/local_widget_state_approaches/pull/3
åæããŸããããç§ã¯ããã«ã€ããŠå¿é ããŠããŸããã useAnimationControllerã¯ãããšãã°ããŠãŒã¶ãŒãSingleTickerProviderãæ°ã«ããå¿ èŠã¯ãããŸããã
AutomaritKeepAliveã¯åãæ²»çã®æ©æµãåããå¯èœæ§ããããŸãã
ç§ãèããŠããããšã®1ã€ã¯ããuseKeepAliveïŒboolïŒãããã¯ãæã€ããšã§ãã
ããã«ãããããã¯ã¹ã€ã³ãšãsuper.buildïŒcontextïŒãã®äž¡æ¹ãåé¿ãããŸãïŒåŸè ã¯éåžžã«æ··ä¹±ããŸãïŒ
ãã1ã€ã®èå³æ·±ãç¹ã¯ããªãã¡ã¯ã¿ãªã³ã°äžã«å¿ èŠãªå€æŽã§ãã
ããšãã°ãçã®ã¢ãããŒããšããã¯ã®TickerMode
ãå®è£
ããããã«å¿
èŠãªå€æŽã®éããæ¯èŒã§ããŸãã
ä»ã®ããã€ãã®ããšãdiffã§æ··åãããŠããŸããããããã次ã®ããšãããããŸãã
Imoããã¯éåžžã«éèŠã§ããããã®ã¹ã¿ã€ã«ã®èªå·±å®çµåã®ç¶æ ãªããžã§ã¯ãããã®éèŠãªåå©ã§ãã ããªãŒå ã®ãã¹ããããã³ã³ããã¹ãã«åºã¥ããŠãã¹ãŠãæã€ããšã¯ããªãã¡ã¯ã¿ãªã³ã°ãšå€æŽãåºæ¬çã«é£ãããè€éã«ãªããŸããããã¯ããããžã§ã¯ãã®éçšã§ãã³ãŒãããŒã¹ã®æçµå質ã«ç®ã«èŠããªããæ確ãªåœ±é¿ãåãŒããŸãã
åæããŸããïŒ
ããã«ãããã³ãŒãã¬ãã¥ãŒãéåžžã«èªã¿ããããªããŸãã
final value = useSomething();
+ final value2 = useSomethingElse();
return Container(
color: value.color,
- child: Text('${value.name}'),
+ child: Text('${value.name} $value2'),
);
察ïŒ
return SomethingBuilder(
builder: (context, value) {
- return Container(
- color: value.color,
- child: Text('$value'),
+ return SomethingElseBuilder(
+ builder: (context, value2) {
+ return Container(
+ color: value.color,
+ child: Text('${value.name} $value2'),
+ );
+ }
);
},
);
2çªç®ã®å·®åã§ã¯ã Container
ãå€æŽãããŠãããã Text
ã®ã¿ãå€æŽãããŠããããšã¯æããã§ã¯ãããŸããã
@rrousselGitããŒã¯ãŒããµããŒãã§ã©ã®ããã«èŠããããè¡šãããŒãžã§ã³ãè©ŠããŠã¿ãã®ã¯çã«ããªã£ãŠãããšæããŸããïŒ å°çšã®ãuseãããŒã¯ãŒããæã€ããã¯ãšå®è³ªçã«äŒŒãŠããŸããããããšããã©ããŒãããããªããŸããïŒ ããã¯ã¢ãããŒããåçãªè¶³å Žã§æ¯èŒããã®ã¯é£ããã®ã§ãuseEffectãuseMemoãªã©ã®å€åœã®æŠå¿µãéåžžã«å€ãããããå®éãããéæ³ã®ããã«èŠãããšæããŸããïŒ
ãã1ã€æ³šæãã¹ãç¹ã¯ãããããã¹ãŠå®éã«å®¶ã«åž°ãã®ã¯ãè€æ°ã®ãŠã£ãžã§ãããããå Žåããã¹ãŠããã®ãã«ã©ãŒã¹ãããã³ã°ãããžãã¯ãå ±æããå¿ èŠãããããçµæã®è²ããŸã£ããç°ãªãæ¹æ³ã§äœ¿çšããããšã§ãã ããã¯ã¹ã¿ã€ã«ã®ã¢ãããŒãã§ã¯ãåå©çšããã®ã«æå³ã®ããããžãã¯ããã³ãã«ããã ãã§ãããã䜿çšããã ãã§ãã ç§ãã¡ã匷ãããã建ç¯äžã®ã³ãŒããŒã¯ãããŸãããããã¯æ¬åœã«äžå¯ç¥è«çã§æè»æ§ããããŸãã
ã¹ããŒããã«ã¢ãããŒãã§ã¯ã
ç§ãæãéèŠãªããšã¯ãåŸè ã§ã¯ãããã«ã¢ãŒããã¯ãã£ã®åé¡ãçºçãããšããããšã§ãããããããªãŒã®ã©ãã«é 眮ããã°ããã§ããããããã«ãã»ã«åããã«ã¯ã©ãããã°ããã§ããããã«ããŒã«ããå¿ èŠããããŸããããããšãã«ã¹ã¿ã ãŠã£ãžã§ããã«ããå¿ èŠããããŸããïŒ åè ã®å Žåãåå©çšãããããžãã¯ã®ãã®ãã£ã³ã¯ãã©ã®ãã¡ã€ã«ã«ä¿åããããå¯äžã®æ±ºå®ã§ãããããªãŒãžã®åœ±é¿ã¯ãŸã£ãããããŸããã ããã¯ããããã®ããžãã¯ã«ãã»ã«åã®ããã€ããäžç·ã«äœ¿çšããããéå±€å ã§äžäžã«ç§»åããããå åŒãŠã£ãžã§ããã«ç§»åãããããå Žåã«ãã¢ãŒããã¯ãã£çã«éåžžã«äŸ¿å©ã§ãã
ç§ã¯æ±ºããŠå°é家ã®éçºè ã§ã¯ãããŸããã ããããããžãã¯ã
ç§ã¯é·ãéVue.jsã䜿çšããŠããŸãããã次ã®ããŒãžã§ã³çšã«ç¬èªã®APIïŒHooksããã€ã³ã¹ãã¬ãŒã·ã§ã³ãåŸããã®ïŒãæã£ãŠããã®ã§ãäžèŠã®äŸ¡å€ããããããããŸããã
ãããŠCMIIWã¯ãreactããã¯ã®ã«ãŒã«ïŒæ¡ä»¶ä»ãã䜿çšããªãïŒã¯CompositionAPIã«ã¯é©çšãããªããšæããŸãã ãããã£ãŠãã«ãŒã«ãé©çšããããã«ãªã³ã¿ãŒã䜿çšããå¿ èŠã¯ãããŸããã
ããã§ããåæ©ä»ãã®ã»ã¯ã·ã§ã³ã§OPã匷åã«åŒ·åããŠããŸãã
åæ©
è€éãªã³ã³ããŒãã³ãã®ã³ãŒãã¯ãæ©èœãæéã®çµéãšãšãã«å€§ãããªãã«ã€ããŠãæšè«ããã®ãé£ãããªããŸãã ããã¯ç¹ã«ãéçºè ãèªåã§äœæããŠããªãã³ãŒããèªãã§ãããšãã«çºçããŸãã
[ãããŸãã]è€æ°ã®ã³ã³ããŒãã³ãéã§ããžãã¯ãæœåºããŠåå©çšããããã®ã¯ãªãŒã³ã§ã³ã¹ãã®ããããªãã¡ã«ããºã ã®æ¬ åŠã
ãã¯ãªãŒã³ããšãç¡æããšããããŒã¯ãŒãããããŸãã Mixinã¯ç¡æã§ãããã¯ãªãŒã³ã§ã¯ãããŸããã ãã«ããŒã¯ã¯ãªãŒã³ã§ãããèªã¿ãããã®æå³ã§ãããŠã£ãžã§ããã®ã¢ãŒããã¯ãã£ã®æå³ã§ããããªãŒå ã移åããããéå±€ã®èŠ³ç¹ããæšè«ãããããã®ãé£ãããããã³ã¹ããããããŸããã
ãŸããããã¯èªã¿ãããã®è°è«ã§æ³šæããããšãéèŠã ãšæããŸãããç¹ã«éçºè ãèªåã§æžããã®ã§ã¯ãªãã³ãŒããèªãã§ãããšãã«èµ·ãããŸããã ãã¡ããããã¹ãããããã«ããŒã¯èªã¿ããããããããŸãããããã«äœãããããç¥ã£ãŠããŠãå¿«é©ã«ã¹ãããã§ããŸãã倧èŠæš¡ãªãããžã§ã¯ãã§è¡ãããã«ãä»ã®èª°ãã®ã³ãŒãããæ°é±é/æ°ãæåã®ç¬èªã®ã³ãŒããèªãã§ããŸãããããã®ãã®ã解æããã³ãªãã¡ã¯ã¿ãªã³ã°ããã®ãé¢å/é£ããã
ä»ã®ããã€ãã®ç¹ã«é¢é£ããã»ã¯ã·ã§ã³ã
åã«ã³ã³ããŒãã³ããçšæããã ãã§ã¯äžååãªçç±ïŒ
...ã³ã³ããŒãã³ããäœæãããšãã€ã³ã¿ãŒãã§ã€ã¹ã®ç¹°ãè¿ãå¯èœãªéšåãšãã®æ©èœãçµã¿åãããŠãåå©çšå¯èœãªã³ãŒãã«æœåºã§ããŸãã ããã ãã§ããä¿å®æ§ãšæè»æ§ã®ç¹ã§ã¢ããªã±ãŒã·ã§ã³ãããªãé ããŸã§å°éãããããšãã§ããŸãã ãã ããç§ãã¡ã®éåçãªçµéšãããç¹ã«ã¢ããªã±ãŒã·ã§ã³ãéåžžã«å€§ãããªã£ãŠããå Žåã¯ãããã ãã§ã¯äžååã§ããå¯èœæ§ãããããšã蚌æãããŠããŸããæ°çŸã®ã³ã³ããŒãã³ããèããŠã¿ãŠãã ããã ãã®ãããªå€§èŠæš¡ãªã¢ããªã±ãŒã·ã§ã³ãæ±ãå Žåãã³ãŒãã®å ±æãšåå©çšãç¹ã«éèŠã«ãªããŸãã
è«ççãªæçåãæžãããç©äºããã匷åã«ã«ãã»ã«åããããšããªãåå©ã§ãããã«ã€ããŠïŒ
æçåã¯ãè€éãªã³ã³ããŒãã³ããç解ããŠç¶æããããšãå°é£ã«ãããã®ã§ãã ãªãã·ã§ã³ã®åé¢ã¯ãæ ¹åºã«ããè«ççãªæžå¿µãèŠãé ããŸãã ããã«ãåäžã®è«ççãªæžå¿µäºé ã«åãçµãå Žåãé¢é£ããã³ãŒãã®ãªãã·ã§ã³ãããã¯ãåžžã«ããžã£ã³ããããå¿ èŠããããŸãã åãè«ççãªæžå¿µã«é¢é£ããã³ãŒãã䜵眮ã§ããã°ãã¯ããã«è¯ãã§ãããã
ç§ãæåºãããã®ä»¥å€ã«ãç§ãã¡ãæ¹åããããšããŠããæšæºçãªäŸã«ã€ããŠä»ã®ææ¡ããããã©ããç¥ãããã§ãã
ããã人ã
ã䜿ãããåºçºç¹ã§ãããªããããã¯çŽ æŽãããããšã§ãã ãã ããçŸæç¹ã§ã®æ倧ã®åé¡ã¯åé·æ§ã§ãã ãã®äŸã§åå©çšããã³ãŒãã¯ããŸããããŸããã ãããã£ãŠãOPã§èª¬æãããŠããããã«ããããåé¡ã®é©åãªè¡šçŸã§ãããã©ããã¯ç§ã«ã¯ããããŸããã
å人çã«æ±ããŠããç¹æ§ããœãªã¥ãŒã·ã§ã³ã§è¡šçŸããæ¹æ³ãããå°ãèããŠãããšãããçŸåšã®ããã¯ã®ææ¡ã§èŠããã倧ããªåé¡ã®ã²ãšã€ã«æ°ã¥ããŸããããããç§ãããããªãçç±ã®1ã€ã§ãããããFlutterãã¬ãŒã ã¯ãŒã¯ã«ããŒãžãããïŒããŒã«ãªãã£ãšã«ãã»ã«åããŸãã¯ããããã®æ¬ åŠã ããã¯ã®èšèšã§ã¯ãã°ããŒãã«ç¶æ
ã䜿çšããŸãïŒããšãã°ãçŸåšæ§ç¯ãããŠãããŠã£ãžã§ããã远跡ããããã®éçç¶æ
ïŒã ç§èŠããã¯é¿ããã¹ãèšèšäžã®ç¹åŸŽã§ãã äžè¬ã«ãAPIãèªå·±å®çµåã«ããããšããŠããããã1ã€ã®ãã©ã¡ãŒã¿ãŒã䜿çšããŠé¢æ°ãåŒã³åºãå Žåããã®ãã©ã¡ãŒã¿ãŒä»¥å€ã®å€ã§ã¯äœãå®è¡ã§ããªãããšã確信ããå¿
èŠããããŸãïŒããããBuildContextãæž¡ãçç±ã§ãïŒ ã useContext
çžåœãããã®ã§ã¯ãªãïŒã ããã誰ããå¿
ç¶çã«æãã§ããç¹æ§ã ãšèšã£ãŠããã®ã§ã¯ãããŸããã ãã¡ãããåé¡ããªããã°ããã¯ã䜿çšããããšãã§ããŸãã ããã¯ç§ãFlutterã§ãã£ãšãããªãããã«ãããããšã§ãã ã°ããŒãã«ãªç¶æ
ïŒãã€ã³ãã£ã³ã°ãªã©ïŒãçºçãããã³ã«ãåŸæããããšã«ãªããŸãã
ããã¯ã¯ããããã³ã³ããã¹ãäžã®ã¡ãœããã§ããå¯èœæ§ããããŸããïŒåæããŒãžã§ã³ã ã£ããšæããŸãïŒãæ£çŽãªãšãããçŸåšã®ããã«ããã¯ãããŒãžããããšã«ã¯ããŸã䟡å€ããããŸããã ããŒãžã«ã¯ãããã©ãŒãã³ã¹ã®åäžãç¹å®ã®ãããã°ããŒã«ã®ããã¯ãªã©ãããã±ãŒãžãåé¢ããããã®ããã€ãã®å©ç¹ãå¿ èŠã«ãªããŸãã ããããªããšãæ··ä¹±ãå¢ããã ãã§ããããšãã°ããªã¹ãã³ã°å¯èœãªãã®ãèãã«ã¯ãAnimatedBuilderãStatefulWidgetãuseListenableã®3ã€ã®å ¬åŒãªæ¹æ³ããããŸãã
ã ããç§ã«ãšã£ãŠãè¡ãæ¹æ³ã¯ã³ãŒãçæãæ¹åããããšã§ã-ç§ã¯ããã€ãã®å€æŽãææ¡ããŸããïŒ https ïŒ
ãããã®ææ¡ãå®éã«å®è£ ãããå Žåãã¢ããªã§éæ³ã®SwiftUIã®ãããªãœãªã¥ãŒã·ã§ã³ãå¿ èŠãªäººã¯ãããã±ãŒãžãäœæããã ãã§ãä»ã®äººã«è¿·æããããããšã¯ãããŸããã
ããã¯ã®æå¹æ§ã«ã€ããŠè°è«ããããšã¯ãç§ãç¥ãéãããŸã åé¡ã«åæããŠããªãããããã®æ®µéã§ã¯ãããã¯ããå€ããŠããŸãã
ãã®å·ã§æ°åè¿°ã¹ãããã«ãä»ã«ãå€ãã®è§£æ±ºçãããããã®è€æ°ã¯èšèªæ©èœã§ãã
ããã¯ã¯ãæãåºæ¬çãªåœ¢åŒã§å®è£
ããã®ãæ¯èŒçå®äŸ¡ãªãå¥ã®æè¡ããã®æ¢åã®ãœãªã¥ãŒã·ã§ã³ã®åãªã移æ€çã§ãã
ãã®æ©èœã¯ãSwiftUIãJetpack Composeã®ããã«ãããã¯ãšã¯ãŸã£ããç°ãªããã¹ãåãå¯èœæ§ããããŸãã ãååä»ãããã¯ã¹ã€ã³ãããããŒã¶ã«ããŸãã¯BuildersããããŒã¶ã«ã®ã·ã³ã¿ãã¯ã¹ã·ã¥ã¬ãŒã
ç§ã¯ããã®åé¡ã®æ žå¿ãStreamBuilderã®ãããªãã¿ãŒã³ã®åçŽåãæ±ããŠãããšããäºå®ã䞻匵ããŸãã
ãããŸã§ã®ãã¹ãŠã®ã³ã¡ã³ãã§ã¯ãããŸããŸãªåäœïŒäœ¿ãæšãŠãªããžã§ã¯ãã®äœæãHTTPãªã¯ãšã¹ãã®äœæãªã©ïŒãŸãã¯ããŸããŸãªæ§æã®ææ¡ã®äž¡æ¹ã«ã€ããŠãStreamBuilderã®ä»£æ¿æ¡ã«ã€ããŠèšåããŠããŸããã
ä»ã«äœãèšãã¹ããããããªãã®ã§ãã©ãããã°ãã以äžé²ãããšãã§ãããããããŸããã
ãã®å£°æ@Hixieã§ããªããç解ããŠããªã/åæããŠããªãããã¯äœã§ããïŒ
@rrousselGitããã瀺ã
- StreamBuilderã¯ããã¹ããããŠãããããèªã¿ããããæžã蟌ã¿æ§ãå£ã£ãŠããŸãã
åé·æ§ã¯åé¡ã§ã¯ãªããšæ¢ã«ãã£ããããŸããã ãã¹ãã¯ãåé·ã§ããããšã®ãã1ã€ã®åŽé¢ã§ãã ãã¹ããæ¬åœã«åé¡ã«ãªãå Žåã¯ãPaddingãExpandedãFlexibleãCenterãSizedBoxãããã³å®éã®çç±ãªãã«ãã¹ããè¿œå ããä»ã®ãã¹ãŠã®ãŠã£ãžã§ããã远跡ããå¿ èŠããããŸãã ãã ãããã¹ãã¯ãã¢ããªã·ãã¯ãŠã£ãžã§ãããåå²ããããšã§ç°¡åã«è§£æ±ºã§ããŸãã
ãã¹ãŠã®StatefulWidgetsã«StreamBuilderã®å®è£ ãã³ããŒããŠè²Œãä»ããã®ã¯åççã§ã¯ãããŸãã
StatefulWidgetsãäœæããã³ç Žæ£ããå¿ èŠã®ããã¹ããªãŒã ãäœæããã³ç Žæ£ããã³ãŒãè¡ãã³ããŒããŠè²Œãä»ããããšãæå³ããŸããïŒ ã¯ããããã¯çµ¶å¯Ÿã«åççã§ãã
ç¬èªã®ã¹ããªãŒã ãäœæ/ç Žæ£ããå¿ èŠã®ããæ°çŸã®_different_ã«ã¹ã¿ã StatefulWidgetsïŒããã¯ã®çšèªã§ã䜿çšãïŒã10ãŸãã¯ç¥ãçŠæ¢ããŠããå Žåããããžãã¯ãã®åå©çšãŸãã¯ãã¹ãããã倧ããªåé¡ãçºçããŸããå¿é ããŸãããããããªãç§ã®ã¢ããªãéåžžã«å€ãã®ç°ãªãã¹ããªãŒã ãäœæããªããã°ãªããªãã®ãã«ã€ããŠã
å
¬å¹³ãæãããã«ãç¹å®ã®ãã¿ãŒã³ãèªåã®ã¢ããªã§ã¯åççã§ã¯ãªããšèª°ããèããã®ã¯åé¡ãªããšæããŸãã ïŒããã¯å¿
ããããã¬ãŒã ã¯ãŒã¯ãããããã€ãã£ãã«ãµããŒãããå¿
èŠãããããšãæå³ããããã§ã¯ãããŸããããå°ãªããšãããã±ãŒãžãããã解決ã§ããããã«ããã®ã¯è¯ãããšã§ããïŒèª°ããstream.listen
ãŸãã¯StreamBuilder(stream)
ã©ã¡ãã䜿çšããããªãå Žå
å ¬å¹³ãæãããã«ãç¹å®ã®ãã¿ãŒã³ãèªåã®ã¢ããªã§ã¯åççã§ã¯ãªããšèª°ããèããã®ã¯åé¡ãªããšæããŸãã
ç§ã¯ããªããšåãããŒãžã«100ïŒ
ããŸãã
確ãã«ã人ã
ã¯èªåã®ã¢ããªã§ããããããšãäœã§ãããããšãã§ããŸãã ç§ãåŸãããšããŠããã®ã¯ããã®ã¹ã¬ããã§èª¬æãããŠãããã¹ãŠã®åé¡ãšå°é£ã¯ãæªãããã°ã©ãã³ã°ç¿æ
£ã®çµæã§ãããå®éã«ã¯DartãFlutterãšã¯ã»ãšãã©é¢ä¿ããªããšããããšã§ãã ããã¯ç§ã®æèŠã®ãããªãã®ã§ããããã¡ãã¡ã§æ°åã®ã¹ããªãŒã ãäœæããã¢ããªãæžããŠãã人ãããå Žåã¯ããã¬ãŒã ã¯ãŒã¯ã®ãæ¹åããäŸé Œããåã«ãã¢ããªã®ãã¶ã€ã³ã確èªããå¿
èŠããããŸãã
ããšãã°ããµã³ãã«ãªããžããªã«çµã¿èŸŒãŸããããã¯ã®å®è£ ã
<strong i="10">@override</strong>
Widget build(BuildContext context) {
final value = useAnimation(animation);
final screenHeight = MediaQuery.of(context).size.height;
final textHeight =
useMemoized(() => math.sqrt(screenHeight), [screenHeight]);
return Text(
'Change Duration',
style: TextStyle(fontSize: 10.0 + value * textHeight),
);
}
ç§ã¯ããã«ã€ããŠæªãæ°æã¡ãæã£ãŠããã®ã§ãç§ã¯ããã€ãã®å
éšããã§ãã¯ããäœãèµ·ãã£ãŠããã®ãããã§ãã¯ããããã«ããã€ãã®ãããã°ããªã³ããè¿œå ããŸããã
以äžã®åºåãããListenableããã¯ãã¢ãã¡ãŒã·ã§ã³ãã£ãã¯ããšã«æŽæ°ããã倩æ°ããã§ãã¯ããŠããããšãããããŸãã ã®ããã«ããã®ãªã¹ããã«ãã䜿çšããããŠã£ãžã§ããã¯æŽæ°ãããŸãããïŒ æéã¯å€æŽãããŸãããïŒ ã€ã³ã¹ã¿ã³ã¹ã¯çœ®ãæããããŸãããïŒ
ã¡ã¢åãããããã¯ãç§ã¯ãããšã®ååŒãäœã§ãããããç¥ããŸããã ãããããªããžã§ã¯ãããã£ãã·ã¥ããããšãæå³ããŠããŸããããã«ãããšã«ãŠã£ãžã§ããã¯ãªããžã§ã¯ããå€æŽããããã©ããããã§ãã¯ããŸããïŒ äœïŒ ã©ãããŠïŒ ãã¡ãããã¹ããŒããã«ãŠã£ãžã§ããå
ã§äœ¿çšãããããªãŒã®äžã®ä»ã®ãŠã£ãžã§ãããå€ãå€æŽããå¯èœæ§ããããããå€æŽãããŒãªã³ã°ããå¿
èŠããããŸãã ããã¯æåéãã®ããŒãªã³ã°åäœã§ãããããªã¢ã¯ãã£ããããã°ã©ãã³ã°ãšã¯æ£å察ã§ãã
ããã«æªãããšã«ããnewãããã¯ãšãoldãããã¯ã¯ã©ã¡ããåãã€ã³ã¹ã¿ã³ã¹ã¿ã€ããæã¡ãã©ã¡ããåãå€ãæã¡ãŸãããé¢æ°ã¯å€ãç¹°ãè¿ãåŠçããŠãå€ãå€æŽããããã©ããã確èªããŸãã _ãã¹ãŠã®åäžã®ã¢ãã¡ãŒã·ã§ã³ãã£ãã¯_ã
ããã¯ç§ãåŸãåºåã§ããç¡éã«ã
/flutter (28121): Use hook:_ListenableHook
I/flutter (28121): Is this the current hook:false
I/flutter (28121): 1: --- inside shouldPreserveState ----
I/flutter (28121): Hook1:Instance of '_ListenableHook'
I/flutter (28121): Hook1 keys:null
I/flutter (28121): Hook2 :Instance of '_ListenableHook'
I/flutter (28121): Hook2 keys:null
I/flutter (28121): 2. Shoud we preserve the state of _ListenableHook:true
I/flutter (28121): 3: --------------
I/flutter (28121): checking if the listenable did change
I/flutter (28121): Did the listenable change?false
I/flutter (28121): Use hook:_MemoizedHook<double>
I/flutter (28121): Is this the current hook:false
I/flutter (28121): 1: --- inside shouldPreserveState ----
I/flutter (28121): Hook1:Instance of '_MemoizedHook<double>'
I/flutter (28121): Hook1 keys:[1232.0]
I/flutter (28121): Hook2 :Instance of '_MemoizedHook<double>'
I/flutter (28121): Hook2 keys:[1232.0]
I/flutter (28121): iterating over the hooks keys
I/flutter (28121): 2. Shoud we preserve the state of _MemoizedHook<double>:true
I/flutter (28121): Use hook:_ListenableHook
I/flutter (28121): Is this the current hook:false
I/flutter (28121): 1: --- inside shouldPreserveState ----
I/flutter (28121): Hook1:Instance of '_ListenableHook'
I/flutter (28121): Hook1 keys:null
I/flutter (28121): Hook2 :Instance of '_ListenableHook'
I/flutter (28121): Hook2 keys:null
I/flutter (28121): 2. Shoud we preserve the state of _ListenableHook:true
ãã®ãã¹ãŠã®äœæ¥ã¯ããã¹ãŠã®ã¢ãã¡ãŒã·ã§ã³ãã£ãã¯ã§å®è¡ãããŸãã ãfinalcolor = useAnimationãã®ãããªå¥ã®ããã¯ãè¿œå ãããš
ç§ã¯ããã«åº§ã£ãŠãã¢ããªã®ç¶æ ããŠã£ãžã§ããããŠã£ãžã§ããããªãŒãå€æŽããã«ããã¹ããååŸã«ã¢ãã¡ãŒã·ã§ã³åãããã®ãèŠãŠããŸãããããã§ãããã¯ã¯ããªãŒ/ãŠã£ãžã§ãããæŽæ°ããããã©ãããåžžã«ãã§ãã¯ããŠããŸãã ãããã®ç¹å®ã®ããã¯ãã䜿çšããããã¹ãŠã®ãŠã£ãžã§ããã«ãã®ããŒãªã³ã°åäœãå®è¡ãããã®ã¯æªãããšã§ãã
buildã¡ãœããå
ã§ç¶æ
ãªããžã§ã¯ãã®åæå/æŽæ°/ç Žæ£ããžãã¯ãåŠçããã®ã¯æªãèšèšã§ãã åå©çšæ§ãããããªããŒãããŸãã¯ã³ã°ããã£ãããŒãã§åŸãããæ¹åã®éã¯ãããã©ãŒãã³ã¹ãžã®åœ±é¿ãæ£åœåãããã®ã§ã¯ãããŸããã
ç¹°ãè¿ããŸãããç§ã®æèŠã§ã¯ã ããã¯ã¯ããã±ãŒãžã§ãããããå©çããªãŒããŒããããæ£åœåãããšèããå Žåã¯ã誰ã§ãããã¯ã䜿çšã§ããŸãã
ãŸãããã«ãããã»ã¹å ã®ãã¹ãŠãæœè±¡åããããšãããšãèšèªæ©èœãã³ã³ãã€ã©ããžãã¯ããŸãã¯æœè±¡åã«ãã£ãŠããã®ãããªäžèŠãªãã§ãã¯ãé²ãããšãã§ãããšã¯æããŸããã ãããã£ãŠãStatefulWidgetãæ¡åŒµãããªã©ã®ä»£æ¿æ段ãæ®ãããŠããŸãã ãã§ã«ã§ããããšã§ãäœåºŠãåŽäžãããŸããã
@Hixieããªãã¯è³ªåã«çããŠããŸããã äžèšã®ç®æ¡æžãã§ç解ããŠããªã/åæããŠããªãããšã¯äœã§ããïŒ
ããªããç§ã«äœã瀺ããŠã»ããããç¥ããã«äŸãäœãããšã¯ã§ããŸããã
@Rudiksz確ãã«ãå®éã«æ€èšãããœãªã¥ãŒã·ã§ã³ã¯ãç¶æ³ãæªåãããªãããã«ããããã¡ã€ãªã³ã°ãšãã³ãããŒã¯ãè¡ãå¿ èŠããããŸãã @TimWhitingã«éä¿¡ãã
@rrousselGitããã¯éåžžã«äž»èŠ³çã§ãããããç§ã¯ããã«ã€ããŠéèã«
ååãšããŠãç§ãããªããèŠãŠããåé¡ãçµéšãããã©ããã¯é¢ä¿ãããŸããã ããªãã®çµéšã¯ç§ã®æèŠã«é¢ä¿ãªãæå¹ã§ãã ããšãç§ããããã®åé¡ãæããªããŠããç§ã¯ããªããçµéšããåé¡ã®è§£æ±ºçãèŠã€ããããšã«åãçµãã§ããããã§ãã ç§èªèº«ãåé¡ãçµéšããŠããªãããšã®å¯äžã®åœ±é¿ã¯ããã®è°è«ã§èŠãããã«ãç§ãåé¡ãããç解ããã®ãé£ãããšããããšã§ãã
ç§ãããªãã«ç€ºããŠã»ããã®ã¯ãåãå ¥ããããªããšæãã³ãŒãã£ã³ã°ãã¿ãŒã³
åé¡ã¯ãããªããç§ã«ãšã£ãŠãèªæãã®é åã«ããäœãã®äŸãæ±ããŠãããšããããšã§ãã
ããã€ãäŸãæããŠãããŸããŸããããããªããç解ããŠããªãããšãç解ããŠããªãã®ã§ãããªããäœãæåŸ ããŠããã®ãããããŸããã
ç§ã¯ãã§ã«ç§ãèšããªããã°ãªããªãã£ããã¹ãŠãèšããŸããã
ããªããç解ããŠããªãããšãç解ããã«ç§ãã§ããå¯äžã®ããšã¯ãèªåèªèº«ãç¹°ãè¿ãããšã§ãã
ããã§ããã€ãã®ã¹ãããããå®è¡ããããšãã§ããŸãããããã¯èªåèªèº«ãç¹°ãè¿ãããšãšåãã§ãã
ã¹ããããã圹ã«ç«ããªãã£ãå Žåããããå®è¡ã§ãããšäœãå€ããã®ãããããŸããã
ããã¯ã¹ã€ã³ãšé¢æ°ãStreamBuilderã®å¯èœãªä»£æ¿æ段ã§ãããã©ããã«ã€ããŠã¯ãããã¯ã¯é¢æ°ã䜿çšããŠã¹ããªãŒã ã確å®ã«ãªãã¹ã³ã§ããããšãããªããã瀺ããŠãããšæããŸããããã¯ã¹ã€ã³ã¯ããã§ã¯ã©ã¹ãå®è¡ã§ããããšããã¹ãŠæ確ã«å®è¡ã§ããããããªãããããªãã®ãããããŸããã解決çã«ããªããŸããã
ããã¯ã¯æ©èœãšèŠãªãããã¹ãã§ã¯ãããŸããã
ãããã¯ãIterable / Streamã«äŒŒãæ°ããèšèªæ§é ã§ãã
é¢æ°ã¯ããã¯ãè¡ãããšãè¡ãããšãã§ããŸããâãŠã£ãžã§ãããåæ§ç¯ãããç¶æ ãŸãã¯æ©èœããããŸããã
ããã¯ã¹ã€ã³ã®åé¡ã¯OPã§ç€ºãããŠããŸãã TL; DRïŒå€æ°ã§ååãè¡çªããåãããã¯ã¹ã€ã³ãè€æ°ååå©çšããããšã¯ã§ããŸããã
@rrousselGitãããšãããã€ãã®äŸãäœæããŠãããŸããªãã®ã§ããããŠç§ãæ±ããŠããäŸã¯æçœãªã®ã§ããããã®æçœãªäŸã®ããã€ãããå§ããŠãããããç¹°ãè¿ããŸãããã
äŸãæçœã§ãããšã¯èšããŸããã§ããããåé¡ã¯ãããŸãã
ã€ãŸããæ°ããäŸãäœæããããšã¯ã§ããŸããã ç§ãèšããªããã°ãªããªãããšã¯ãã¹ãŠããã§ã«ãã®ã¹ã¬ããã«ãããŸãïŒ
ãããã®äŸã«è¿œå ãããã®ã¯äœãèããããŸããã
ããããFWIWRiverpodã䜿çšãããªãŒãã³ãœãŒã¹ã®å€©æ°ã¢ããªã«åãçµãã§ããŸãã çµãã£ããããã«ãªã³ã¯ããŸãã
ç§ã¯ãã€ãã¿ãŒã§äžè«èª¿æ»ãè¡ããããã§èª¬æãããŠããåé¡ã«é¢é£ãããã«ããŒã«ã€ããŠããã€ã質åããŸããã
https://twitter.com/remi_rousselet/status/1295453683640078336
æ祚ã¯ãŸã ä¿çäžã§ãããçŸåšã®æ°å€ã¯æ¬¡ã®ãšããã§ãã
200人ã®86ïŒ ãããã¹ãã䌎ããªããã«ããŒãäœæããæ¹æ³ãæãã§ãããšããäºå®ã¯ãããèªäœãç©èªã£ãŠããŸãã
æ確ã«ããããã«ãç§ã¯ãã®åé¡ã«å¯ŸåŠãã¹ãã§ã¯ãªããšææ¡ããããšã¯ãããŸããã 察åŠãã¹ãã§ã¯ãªããšæã£ãããåé¡ã¯è§£æ±ºããŸãã
ãªã³ã¯ããã¹ããããã䜿çšããäŸãäœæããããšæããŸãã
ãªã³ã¯ãããã¹ããããã«åºã¥ããŠäŸãäœæããã®ãæäŒãããšãã§ããŸããããããã®ã¹ãããããååã§ã¯ãªãã£ãçç±ãç¥ãå¿
èŠããããŸã
ãã以å€ã®å Žåãç§ã«ã§ããããšã¯ãããã®ã¹ãããããã³ã³ãã€ã«ããããšã ãã§ããããããããªãã®æãããšã§ã¯ãªãããšæããŸãã
ããšãã°ãããã«å€æ°ã®ValueListenableBuilder + TweenAnimationBuilderhttps ïŒ //gist.github.com/rrousselGit/a48f541ffaaafe257994c6f98992fa73ã«é¢ããèŠç¹ããã
ããšãã°ãããã«å€æ°ã®ValueListenableBuilder + TweenAnimationBuilderhttps ïŒ //gist.github.com/rrousselGit/a48f541ffaaafe257994c6f98992fa73ã«é¢ããèŠç¹ããã
FWIWããã®1ã€ã®ç¹å®ã®äŸã¯ãmobxã§ããç°¡åã«å®è£
ã§ããŸãã
å®éã«ã¯ãããã¯ã®å®è£
ãããçãã§ãã
Mobxã®ãªãã¶ãŒããã«ã¯ã¹ããã€ãã®ValueNotifiersã§ããããã®ObserverãŠã£ãžã§ããã¯Flutterã®ValueListenableBuilderã®é²å圢ã§ã-è€æ°ã®ValueNotifierããªãã¹ã³ã§ããŸãã
ValueNotifier / ValueListenableBuilderã³ã³ãã®ããããã€ã³çœ®æã§ãããšããããšã¯ãæ
£çšçãªFlutterã³ãŒããäœæããããšãæå³ããŸããããã¯ãå®éã«ã¯éèŠãªèŠçŽ ã§ãã
Flutterã«çµã¿èŸŒãŸããŠããTweenãã«ããŒãåŒãç¶ã䜿çšããŠãããããæ°ãããŠã£ãžã§ãã/ããã¯ãåŠç¿/å®è£ ããå¿ èŠã¯ãªãïŒã€ãŸããæ°ããæ©èœã¯å¿ èŠãããŸããïŒãããã¯ã®ããã©ãŒãã³ã¹ãžã®åœ±é¿ã¯ãããŸããã
import 'package:flutter/material.dart';
import 'package:flutter_mobx/flutter_mobx.dart';
import 'counters.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
<strong i="13">@override</strong>
Widget build(BuildContext context) {
return MaterialApp(
home: Home1(),
);
}
}
var counters = Counters();
class Home1 extends StatelessWidget {
<strong i="14">@override</strong>
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Observer(
builder: (context) => TweenAnimationBuilder<int>(
duration: const Duration(seconds: 5),
curve: Curves.easeOut,
tween: IntTween(end: counters.firstCounter),
builder: (context, value, child) {
return Text('$value');
},
),
),
RaisedButton(
onPressed: () => counters.firstCounter += 100,
child: Text('+'),
),
// Both counters have voluntarily a different Curve and duration
Observer(
builder: (context) => TweenAnimationBuilder<int>(
duration: const Duration(seconds: 2),
curve: Curves.easeInOut,
tween: IntTween(end: counters.secondCounter),
builder: (context, value, child) {
return Text('$value');
},
),
),
RaisedButton(
onPressed: () => counters.secondCounter += 100,
child: Text('+'),
),
const Text('total:'),
// The total must take into account the animation of both counters
Observer(
builder: (context) => TweenAnimationBuilder<int>(
duration: const Duration(seconds: 5),
curve: Curves.easeOut,
tween: IntTween(
end: counters.firstCounter + counters.secondCounter),
builder: (context, value, child) {
return Text('$value');
},
),
),
],
),
),
);
}
}
Counters.dartã¯...ãšåããããåçŽã§ã
part 'counters.g.dart';
class Counters = _Counters with _$Counters;
abstract class _Counters with Store {
<strong i="18">@observable</strong>
int firstCounter = 0;
<strong i="19">@observable</strong>
int secondCounter = 0;
}
ããã¯ãanimationbuilderãå¿ èŠãšããªãå¥ã®å®è£ ã§ãã ãŠã£ãžã§ããã®ãã«ãã¡ãœããã¯ãã»ãã³ãã£ãã¯htmlãã¡ã€ã«ã®ããã«...ãã³ãã¬ãŒãã®ããã«ãå¯èœãªéãçŽç²ã§ãã
https://gist.github.com/Rudiksz/cede1a5fe88e992b158ee3bf15858bd9
@Rudiksz ãåèšããã£ãŒã«ãã®åäœã¯ã¹ããããã§å£ããŠããŸãã ããã¯ãäž¡æ¹ã®ã«ãŠã³ã¿ãŒãäžç·ã«ã¢ãã¡ãŒã·ã§ã³åããå¯èœæ§ãããããç°ãªãæéã«ç°ãªãæ²ç·ã§ã¢ãã¡ãŒã·ã§ã³åãçµäºããäŸãšã¯äžèŽããŸããã
åæ§ã«ããã®äŸãValueListenableBuilder
ããªã¢ã³ãã«äœãè¿œå ããã®ãããããŸããã
æåŸã®èŠç¹ãšããŠã TickerProvider
ã¯TickerMode
ãµããŒãããŠããªãããå£ããŠããŸãããŸãããªã¹ããŒãåé€ãããããã³ã³ãããŒã©ãŒãç Žæ£ããããããããšããããŸããã
ãããŠãMobxã¯ãããããããã¯ããå€ããŠããŸãã ã¢ã³ããšã³ãç¶æ / ValueListenable vs Stores vs Streamsãå®è£ ããæ¹æ³ã«ã€ããŠã¯èª¬æããŠããŸããããããŒã«ã«ç¶æ /ãã¹ãããããã«ããŒãåŠçããæ¹æ³ã«ã€ããŠèª¬æããŠããŸããããã¯Mobxã§ã¯è§£æ±ºãããŸããã
ââââ
ãŸããããã¯ã®äŸã§ã¯ã useAnimatedInt
ããã±ãŒãžã«æœåºã§ãã/æœåºããå¿
èŠããããåã
ã®ããã¹ãã¢ãã¡ãŒã·ã§ã³ãšåèšã®éã«æé/æ²ç·ã®éè€ããªãããšã«æ³šæããŠãã ããã
ããã©ãŒãã³ã¹ã«é¢ããŠã¯ãããã¯ã§ã¯1ã€ã®èŠçŽ ã®ã¿ãåæ§ç¯ããŸããããã«ããŒã§ã¯2ã4åã®ãã«ããŒãåæ§ç¯ããŸãã
ãããã£ãŠãããã¯ã¯éåžžã«é«éã«ãªãå¯èœæ§ããããŸãã
ãåèšããã£ãŒã«ãã®åäœã¯ãã¹ããããã§å£ããŠããŸãã ããã¯ãäž¡æ¹ã®ã«ãŠã³ã¿ãŒãäžç·ã«ã¢ãã¡ãŒã·ã§ã³åããå¯èœæ§ãããããç°ãªãæéã«ç°ãªãæ²ç·ã§ã¢ãã¡ãŒã·ã§ã³åãçµäºããäŸãšã¯äžèŽããŸããã
ããªãã¯æããã«ãäŸãå®è¡ããããšããããŸããã§ããã ã³ãŒããšãŸã£ããåãããã«åäœããŸãã
æåŸã®èŠç¹ãšããŠãTickerProviderã¯TickerModeããµããŒãããŠããªããããå£ããŠããŸãã
ãããäœãæå³ããã®ãããããŸããã TickerModeã䜿çšããªã_your_ã®äŸããªãã¡ã¯ã¿ãªã³ã°ããŸããã åã³èŠä»¶ãå€æŽããŠããŸãã
ããã©ãŒãã³ã¹ã«é¢ããŠã¯ãããã¯ã§ã¯1ã€ã®èŠçŽ ã®ã¿ãåæ§ç¯ããŸããããã«ããŒã§ã¯2ã4åã®ãã«ããŒãåæ§ç¯ããŸãã ãããã£ãŠãããã¯ã¯éåžžã«é«éã«ãªãå¯èœæ§ããããŸãã
ãããããããã ããã¯ãŠã£ãžã§ããã¯ããã«ãããšã«å€æŽãåžžã«ããŒãªã³ã°ããŸãã valuelistenablesã«åºã¥ããã«ããŒã¯ããªã¢ã¯ãã£ããã§ãã
åæ§ã«ããã®äŸãValueListenableBuilderããªã¢ã³ãã«äœãè¿œå ããã®ãããããŸããã
ãããŠãMobxã¯ãããããããã¯ããå€ããŠããŸãã ã¢ã³ããšã³ãç¶æ / ValueListenable vs Stores vs Streamsãå®è£ ããæ¹æ³ã«ã€ããŠã¯èª¬æããŠããŸããããããŒã«ã«ç¶æ /ãã¹ãããããã«ããŒãåŠçããæ¹æ³ã«ã€ããŠèª¬æããŠããŸããããã¯Mobxã§ã¯è§£æ±ºãããŸããã
åè«ã§ãããã ç§ã¯ããªãã®äŸãåãäžãããã¹ããããValueListenableBuilders *ãšãã¥ã€ãŒã³ãã«ããŒã§ãååŒãããŸãããïŒïŒ ããªããç¹ã«åé¡ãšããŠæèµ·ããç¹ã
ããããããã§ã®ãã®æã¯ããã®è°è«ã«å¯Ÿããããªãã®å
šäœçãªæ
床ã説æããŠããŸãã ããã¯ã§ãªãå Žåã¯ããããã¯å€ãã§ããã解決çãšããŠäœ¿çšãããã®ãããã¯ã§ãããã©ããã¯æ°ã«ããªããšèšããŸãã
ã¡ãã£ãšäŒæ©ããŠãã ããã
ããªãã¯æããã«ãäŸãå®è¡ããããšããããŸããã§ããã ã³ãŒããšãŸã£ããåãããã«åäœããŸãã
ããã§ã¯ãããŸããã æåã®ã«ãŠã³ã¿ãŒã¯5ç§ä»¥äžã2çªç®ã®ã«ãŠã³ã¿ãŒã¯2ç§ä»¥äžã¢ãã¡ãŒã·ã§ã³ããã©ã¡ããç°ãªãã«ãŒãã䜿çšããŸãã
ç§ãæäŸããäž¡æ¹ã®ã¹ããããã䜿çšãããšãäž¡æ¹ã®ã«ãŠã³ã¿ãŒãåæã«ã€ã³ã¯ãªã¡ã³ãã§ããã¢ãã¡ãŒã·ã§ã³ã®ãã¹ãŠã®ãã¬ãŒã ã§ãåèšããæ£ãããªããŸãã æåã®ã«ãŠã³ã¿ãŒããŸã ã¢ãã¡ãŒã·ã§ã³ããŠããéã«2çªç®ã®ã«ãŠã³ã¿ãŒãã¢ãã¡ãŒã·ã§ã³ãåæ¢ããå Žåã§ã
äžæ¹ãå®è£
ã§ã¯2ã€ã®TweenAnimationBuilderã1ã€ã«ããŒãžãããŠããããããã®ã±ãŒã¹ã¯èæ
®ãããŠããŸããã
ãããä¿®æ£ããã«ã¯ã次ã®ããã«æžãå¿
èŠããããŸãã
Observer(
builder: (context) {
return TweenAnimationBuilder<int>(
duration: const Duration(seconds: 5),
curve: Curves.easeOut,
tween: IntTween(end: counters.firstCounter),
builder: (context) {
return Observer(
valueListenable: secondCounter,
builder: (context, value2, child) {
return TweenAnimationBuilder<int>(
duration: const Duration(seconds: 2),
curve: Curves.easeInOut,
tween: IntTween(end: counters.secondCounter),
builder: (context, value2, child) {
return Text('${value + value2}');
},
);
},
);
},
);
},
)
2ã€ã®TweenAnimationBuilders
ã¯ãäž¡æ¹ã®ã«ãŠã³ã¿ãŒãåå¥ã«ã¢ãã¡ãŒã·ã§ã³åã§ãããšããäºå®ãå°éããããã«å¿
èŠã§ãã ãŸããæåã®Observer
ã¯counters.secondCounter
ç£èŠã§ããªãããã2ã€ã®Observer
ãå¿
èŠã§ãã
ãããããããã ããã¯ãŠã£ãžã§ããã¯ããã«ãããšã«å€æŽãåžžã«ããŒãªã³ã°ããŸãã valuelistenablesã«åºã¥ããã«ããŒã¯ããªã¢ã¯ãã£ããã§ãã
Element
æ©èœãç¡èŠããŠããŸããããã¯ãããã¯ã®æ©èœãšåãã§ããruntimeTypeãšããŒãæ¯èŒããæ°ããèŠçŽ ãäœæããããæ¢åã®èŠçŽ ãæŽæ°ãããã決å®ããŸãã
ç§ã¯ããªãã®äŸãåãäžãããã¹ããããValueListenableBuilders *ãšãã¥ã€ãŒã³ãã«ããŒã§ãååŒãããŸãã
åèšæ°ã®åé¡ãä¿®æ£ããããšãããšãã©ã®ãã¹ããåé€ãããŸãããïŒ
Observer(
builder: (context) => TweenAnimationBuilder<int>(
duration: const Duration(seconds: 5),
curve: Curves.easeOut,
tween: IntTween(end: counters.firstCounter),
builder: (context, value, child) {
return Text('$value');
},
),
),
ãšéãã¯ãããŸããïŒ
ValueListenableBuilder<int>(
valueListenable: firstCounter,
builder: (context, value, child) => TweenAnimationBuilder<int>(
duration: const Duration(seconds: 5),
curve: Curves.easeOut,
tween: IntTween(end: value),
builder: (context, value, child) {
return Text('$value');
},
),
),
å ¥ãåã®èŠ³ç¹ããã
ããªããããªãã®èŠç¹ã«èšåããŠãããªããç§ãåã«è¿°ã¹ãããã«ããã®ã¢ãããŒãã¯TickerProvider
/ TickerMode
ç ŽããŸãã vsync
ã¯ã SingleTickerProviderClientStateMixin
ã䜿çšããŠååŸããå¿
èŠããããŸããããããªããšããã¥ãŒãã£ã³ã°ããžãã¯ããµããŒããããªããããããã©ãŒãã³ã¹ã®åé¡ãçºçããå¯èœæ§ããããŸãã
ç§ã®èšäºã§ããã説æããŸããïŒ https ïŒ
ãããŠããã®ã¢ãããŒãã§ã¯ãå ã TweenAnimationBuilderãå¿ èŠãªãã¹ãŠã®å Žæã«Tweenããžãã¯ãåå®è£ ããå¿ èŠããããŸãã ããã¯ãç¹ã«ããžãã¯ãããã»ã©ç°¡åã§ã¯ãªãããšãèãããšãé倧ãªéè€ã«ã€ãªãããŸã
ç§ãæäŸããäž¡æ¹ã®ã¹ããããã䜿çšãããšãäž¡æ¹ã®ã«ãŠã³ã¿ãŒãåæã«ã€ã³ã¯ãªã¡ã³ãã§ããã¢ãã¡ãŒã·ã§ã³ã®ãã¹ãŠã®ãã¬ãŒã ã§ãåèšããæ£ãããªããŸãã æåã®ã«ãŠã³ã¿ãŒããŸã ã¢ãã¡ãŒã·ã§ã³ããŠããéã«2çªç®ã®ã«ãŠã³ã¿ãŒãã¢ãã¡ãŒã·ã§ã³ãåæ¢ããå Žåã§ã
äžæ¹ãå®è£ ã§ã¯2ã€ã®TweenAnimationBuilderã1ã€ã«ããŒãžãããŠããããããã®ã±ãŒã¹ã¯èæ ®ãããŠããŸããã
ã¯ããããã¯ç§ãåãã§è¡ã£ããã¬ãŒããªãã§ãã ã¢ãã¡ãŒã·ã§ã³ãå€åãèµ·ãã£ããšãã®èŠèŠçãªãã£ãŒãããã¯ã«ãããã粟床ãéèŠã§ã¯ãªãå Žåã¯ç°¡åã«æ³åã§ããŸãã ããã¯ãã¹ãŠèŠä»¶ã«äŸåããŸãã
ããããç§ã¯ããªããå察ããã ãããšæã£ãã®ã§ãã³ãŒããããã«ã¯ãªãŒã³ã«ããªããããã®æ£ç¢ºãªåé¡ã解決ãã2çªç®ã®ããŒãžã§ã³ã
ããªããããªãã®èŠç¹ãåç §ããŠãããªããç§ãåã«è¿°ã¹ãããã«ããã®ã¢ãããŒãã¯TickerProvider / TickerModeãå£ããŸãã vsyncã¯ãSingleTickerProviderClientStateMixinã䜿çšããŠååŸããå¿ èŠããããŸããããããªããšãããã©ãŒãã³ã¹ã®åé¡ãåŒãèµ·ããå¯èœæ§ã®ãããã¥ãŒãã£ã³ã°ããžãã¯ããµããŒãããŸããã
ãããã£ãŠããŠã£ãžã§ããã§ãã£ãã«ãŒãããã€ããŒãäœæãããããã«ãŠã³ã¿ãŒã«æž¡ããŸãã ã¢ãã¡ãŒã·ã§ã³ã³ã³ãããŒã©ãŒãåŠåããŸããã§ããã ãããã®è©³çŽ°ã¯å®è£ ããã®ãéåžžã«ç°¡åã§ãäŸã«äœããè¿œå ãããããªæ°ãããŸããã§ããã ããããããã§ç§ãã¡ã¯ããããããç¬ã£ãŠããŸãã
ç§ã¯CounterïŒïŒã¯ã©ã¹ãå®è£ ããŠãããªãã®äŸãè¡ãããšã ããå®è¡ããŸããã
ãããŠããã®ã¢ãããŒãã§ã¯ãå ã TweenAnimationBuilderãå¿ èŠãªãã¹ãŠã®å Žæã«Tweenããžãã¯ãåå®è£ ããå¿ èŠããããŸãã ããã¯ãç¹ã«ããžãã¯ãããã»ã©ç°¡åã§ã¯ãªãããšãèãããšãé倧ãªéè€ã«ã€ãªãããŸã
äœïŒ ã©ãããŠïŒ Pleasaeã¯ãCounterã¯ã©ã¹ã®ã€ã³ã¹ã¿ã³ã¹ãè€æ°äœæããŠãããŸããŸãªãŠã£ãžã§ããã§äœ¿çšã§ããªãã®ã¯ãªãã§ããïŒ
@Rudikszããªãã®è§£æ±ºçãå®éã«è¿°ã¹ãããåé¡ã解決ããŠãããã©ããã¯
ç§ã¯CounterïŒïŒã¯ã©ã¹ãå®è£ ããŠãããªãã®äŸãè¡ãããšã ããå®è¡ããŸããã
ããã§ã
ã¯ããããã¯ç§ãåãã§è¡ã£ããã¬ãŒããªãã§ãã ã¢ãã¡ãŒã·ã§ã³ãå€åãèµ·ãã£ããšãã®èŠèŠçãªãã£ãŒãããã¯ã«ãããã粟床ãéèŠã§ã¯ãªãå Žåã¯ç°¡åã«æ³åã§ããŸãã ããã¯ãã¹ãŠèŠä»¶ã«äŸåããŸãã
ãããã£ãŠããŠã£ãžã§ããã§ãã£ãã«ãŒãããã€ããŒãäœæãããããã«ãŠã³ã¿ãŒã«æž¡ããŸãã ã¢ãã¡ãŒã·ã§ã³ã³ã³ãããŒã©ãŒãåŠåããŸããã§ããã ãããã®è©³çŽ°ã¯å®è£ ããã®ãéåžžã«ç°¡åã§ãäŸã«äœããè¿œå ãããããªæ°ãããŸããã§ããã ããããããã§ç§ãã¡ã¯ããããããç¬ã£ãŠããŸãã
è¡šé¢äžã¯@rrousselGitã®ããã¯ããŒãžã§ã³ãšåçã®ã³ãŒããæäŸããŸããããããã¯ããŒãžã§ã³ã«å«ãŸããéšåã@TimWhitingã®ãªããžããªãäœæããçç±ã§ãã ãã¹ãŠã®èŠä»¶ãæºãããŠãããšæãããå Žåã¯ãããã«ãœãªã¥ãŒã·ã§ã³ãéä¿¡ã§ããŸãã
ããªãã¯æããã«ãäŸãå®è¡ããããšããããŸããã§ããã ã³ãŒããšãŸã£ããåãããã«åäœããŸãã
ãããããããã
åè«ã§ãããã ç§ã¯ããªãã®äŸãåãäžãããã¹ããããValueListenableBuilders *ãšãã¥ã€ãŒã³ãã«ããŒã§ãååŒãããŸãã
ãã®ãããªéé£ã¯ãé æ ®ãã ãããæ ¹æ¬çãªåé¡ã解決ããã«ããã®ã¹ã¬ããã掻æ°ã«æºã¡ããã®ã«ããã ãã§ãã ãã®ã¹ã¬ããã§ç§ãèŠãã³ã¡ã³ãã®çµæã§ãããçžæãéé£ããããè称ããããæã£ããããããšãªããããªãã¯ããªãã®äž»åŒµãããããšãã§ããŸããç§ã¯ããªãã«å¯Ÿããä»ã®äººããã®ãã®ãããªè¡åãèŠãŸããã ãŸããèªåã®æçš¿ã«çµµæåãåå¿ãããå¹æãããããŸããã
@rrousselGit
ãªã³ã¯ãããã¹ããããã«åºã¥ããŠäŸãäœæããã®ãæäŒãããšãã§ããŸããããããã®ã¹ãããããååã§ã¯ãªãã£ãçç±ãç¥ãå¿ èŠããããŸã
ãã以å€ã®å Žåãç§ã«ã§ããããšã¯ãããã®ã¹ãããããã³ã³ãã€ã«ããããšã ãã§ããããããããªãã®æãããšã§ã¯ãªãããšæããŸãã
ã¹ããããã ãã§ãªããããè€éãªã¢ããªãæ±ããŠããçç±ã¯ãã¹ããããã®1ã€ãåŠçããäŸãæçš¿ãããšãã«ããã以å€ã®ã±ãŒã¹ãåŠçããªãã£ããããããã§ã¯äžååã ãšèšã£ãããã§ããã¹ããããã«å«ãŸããŠããŸããïŒããšãã°ãdidUpdateWidgetãåŠçããªãã£ãããããã®ã¹ããããã2ã€äžŠã¹ãŠåŠçããªãã£ãããŸãã¯ãã®ä»ã®å®å šã«åççãªåŠçãè¡ããŸããã§ããïŒã ãã粟巧ãªã¢ããªã§ååã«ç²Ÿå·§ã«ã§ããããšãæãã§ããŸãã解決çãããã°ãåŠçãå¿ èŠãªæ°ããåé¡ãçºçãããèœãšãç©Žãã®ç¬éã¯ãããŸããã ãã¡ãããåŠçãå¿ èŠãªãã®ãèŠéããŠããŸãå¯èœæ§ã¯ãããŸããããã®å¯èœæ§ãæå°éã«æããããšãç®çã§ãã
æè¿ã®ããŸãæè¿ãããŠããªãæçš¿ã«ã€ããŠã¯ãå°ããªäŸã§ååŸã«æŠãã®ã§ã¯ãªãã @ TimWhitingã®ãªããžããªã§äŸãäœæããããšã«çŠç¹ãåœãŠãŸãããã ãã§ã«èª¬æããããã«ãå°ããªäŸã¯ã代æ¿æ¡ãå®éã«ããŸãæ©èœããããšã蚌æããã®ã«ååãªä»£è¡šãšãªãã»ã©ç²Ÿå·§ãªãã®ã«ãªãããšã¯æ±ºããŠãããŸããã
ãã¹ãŠã®èŠä»¶ãæºãããŠãããšæãããå Žåã¯ãããã«ãœãªã¥ãŒã·ã§ã³ãéä¿¡ã§ããŸãã
èŠä»¶ã¯äºåŸã«å€æŽãããŸããã ç§ã¯2ã€ã®è§£æ±ºçãæäŸããŸããã 劥åãããã®ïŒéåžžã«åççãªãã®ïŒãšãæäŸãããäŸã®æ£ç¢ºãªåäœãå®è£ ãããã®ã
è¡šé¢äžã¯@rrousselGitã®ããã¯ããŒãžã§ã³ãšåçã®ã³ãŒããæäŸããŸããããå®éã«ã¯åçã§ã¯ãããŸããã
ãããã¯ãœãªã¥ãŒã·ã§ã³ãã¯å®è£ ããŸããã§ãããç¹ã«ããã¹ãã®åé¡ãã«çŠç¹ãåœãŠãŠãValueListenableBuilderã®äŸãå®è£ ããŸããã ããã¯ãè¡ããã¹ãŠã®ããšãå®è¡ããããã§ã¯ãããŸãããå¥ã®ãœãªã¥ãŒã·ã§ã³ã䜿çšããŠãäžæºã®ç®æ¡æžããªã¹ãã®1ã€ã®é ç®ãç°¡ç¥åããæ¹æ³ã玹ä»ããŸããã
å€éšããã±ãŒãžããã£ã¹ã«ãã·ã§ã³ã«æã¡èŸŒãããšãèš±å¯ãããŠããå Žåã¯ãç§ãããã§ãã
åå©çšæ§ïŒä»¥äžã®ãªããžããªã®äŸãã芧ãã ãã
https://github.com/Rudiksz/cbl_example
ããŒãïŒ
ç·šéïŒãã®äŸã«ã¯ãã°ããããŸããå€æŽãã¢ãã¡ãŒã·ã§ã³åãããŠãããšãã«ãã€ã³ã¯ãªã¡ã³ãããéå§ãããšãã«ãŠã³ã¿ãŒããªã»ãããããçŸåšã®å€ããã€ã³ã¯ãªã¡ã³ããããŸãã ãããã®ãã«ãŠã³ã¿ãŒãã«å¯Ÿããæ£ç¢ºãªèŠä»¶ãããããªããããæå³çã«ä¿®æ£ããŸããã§ããã ãã®åé¡ãä¿®æ£ããããã«ãã€ã³ã¯ãªã¡ã³ã/ãã¯ãªã¡ã³ãæ¹æ³ãå€æŽããã®ã¯ç°¡åã§ãã
以äžã§ãã
@Hixieç§ã®äŸïŒhttps://github.com/TimWhiting/local_widget_state_approaches/blob/master/lib/hooks/animated_counter.dartïŒãååã§ã¯ãªããšããèšãæ¹ãšããŠãããªãã®ã³ã¡ã³ãã解éããå¿ èŠããããŸããïŒ
ãŸããZoom / Googleã®ããŒãã³ãŒã«ã¯ãããŸããïŒ
ãŸããèªåã®æçš¿ã«çµµæåãåå¿ãããå¹æãããããŸããã
äœããªãã ããã¯äœã«ãå šãç¡é¢ä¿ã§ãã ãªããããè²ãŠãã®ã§ããïŒ
@rrousselGitãããååãã©ãããç¥ãããšãã§ããã®ã¯ããªãã ãã§ãã ãã®äŸããªãã¡ã¯ã¿ãªã³ã°ããŠãã¯ãªãŒã³ã§çããéè€ããã³ãŒãããªãããã«ããæ¹æ³ãèŠã€ããããæºè¶³ããŸããïŒ ãŸãã¯ããã®ãã°ãæºããããã«åŠçããå¿ èŠãããããã®äŸã§ã¯åŠçãããªãããµããŒãããå¿ èŠããããšæããããã®ã¯ãããŸããïŒ
ãããååãã©ãããç¥ãããšãã§ããã®ã¯ããªãã ãã§ã
ç§ã¯ãã®å€æãäžãããšã¯ã§ããŸããã ãããããæéã®ã¢ããªã±ãŒã·ã§ã³ã䜿ã£ãŠåé¡ãæããããšãã§ãããšã¯æããŸããã
ç§ã¯ããªããç§ã«æãã§ããããã«åããŠãããŸããŸãããããããç§ãã¡ãã©ã®ããã«é²æ©ããããç解ããŠããªãã®ã§ãç§ã¯æå°ãå¿ èŠã§ãã
ç§ãã¡ã®èŠç¹ããåé¡ã瀺ã倧éã®ã³ãŒãã¹ãããããæäŸãããšæããŸãã 瀺ãããŠãããã®ããããããŠããªãå Žåãç§ã¯æ¬åœã«ããå€ãã®ã³ãŒãäŸãéããŠããæ確ã«ãªããšã¯æããŸããã
ããšãã°ãèªãã®ãæããããã¹ãããããã«ããŒãè€æ°ããå Žåãããã°ã®å¯èœæ§ãé«ã50è¡ã®çŽç²ãªå®åæãåé¡ãååã«ç€ºããŠããªãå Žåãã©ãã«ãè¡ããŸããã
ããã¯ã¹ã€ã³ãæäŸããã®ã¯éåžžã«å¥åŠã§ãããé¢æ°ãããã§ã®è§£æ±ºçã§ãããaskå šäœãã«ãã»ã«åãããç¶æ ã§ãã
ç§ã«ãšã£ãŠãç§ãã¡ã¯å°çã«2ãã€ã³ããæã¡è² ããããšæããŸãããããŠç§ã¯ã©ã¡ãããšçå£ã«è°è«ããããšã¯ã§ããªããšæããŸãã
äœåºŠãè¿°ã¹ãããŠããããã«ããããŠRemiã®äžè«èª¿æ»ã§ããç°¡åã«èšãã°ã次ã®ããã«èšããŸãããã«ããŒã®åé·æ§ããã¹ããããã¯ããŒãžã£ãŒãªãã§ããã«ããŒã®æ©èœãå¿ èŠã§ãã ããã¯å®å šã«èŠçŽããŠããŸãããïŒ ããã«é²ãããã«ããã«ã³ãŒãäŸãå¿ èŠãªçç±ã¯å®å šã«æ··ä¹±ããŠããŸãã
Remiã®äžè«èª¿æ»ã§ã¯ãFlutteréçºè ã®çŽ80ïŒ ããå¯èœãªå Žåã¯ã³ãŒãå ã®ãã¹ãããããã«ããŒãåé¿ããããã®äœããã®æ©èœã奜ãããšã瀺ãããŠããŸãã ããã¯æ¬åœã«ããèªäœãimoã§ãã ã³ãã¥ããã£ã®ææ ãéåžžã«æ確ãªå Žåã¯ããã®ã¹ã¬ããã§ç§ãã¡ãããããååŸããå¿ èŠã¯ãããŸããã
ç§ã®èŠè§£ã§ã¯ãåé¡ã¯æ確ã§ãããããã§çè«çæ ¹æ ã説æããããã«æ®µèœãæ§ãã競åãããã¬ãŒã ã¯ãŒã¯ãèŠããšãåé¡ã¯ããã«æ確ã«ãªããŸãã VueãReactãFlutterã¯ãã¹ãŠããšãã§ããããã¹ãŠReactãã掟çããŠããããŠã£ãžã§ããã®ã©ã€ããµã€ã¯ã«ã«çµã³ä»ããªããã°ãªããªãç¶æ ãåå©çšãããšãããã®åé¡ã«çŽé¢ããŠããŸãã ãããã¯ãã¹ãŠããªããã®ãããªãã®ãå®è£ ããã®ãã詳现ã«èª¬æããŠããŸãã 倧äžå€«ã§ãã ããã¯ãã¹ãŠé¢é£ããŠããŸãã
@rrousselGitè€æ°ã®ããã¯ãããäŸãæããŠ
List<AnimationController> controllers = [];
int numAnimationControllers = 50;
<strong i="7">@override</strong>
void initState() {
for (int i = 0; i < numAnimationControllers; i++)
controllers.add(AnimationController(...));
}
<strong i="8">@override</strong>
void dispose() {
for (int i = 0; i < numAnimationControllers; i++)
controllers[i].dispose();
}
ããããããã¯ã䜿çšãããšãã«ãŒãå
ã§useAnimationController
ãåŒã³åºãããšã¯ã§ããŸããã ããã¯äºçŽ°ãªäŸã ãšæããŸããããã®ã¿ã€ãã®ãŠãŒã¹ã±ãŒã¹ã®è§£æ±ºçã¯ã©ãã«ãèŠã€ãããŸããã§ããã
@satvikpendem
æ¬çªç°å¢ã«ããç§ã®ã¢ããªã®ããã€ãã®äŸïŒããŒãžä»ãã䜿çšããŠãªã¯ãšã¹ããéä¿¡ãããªã©ã®ããã¯ã®äžéšã¯ãåäžã®ããã¯ã«ããŒãž/ãªãã¡ã¯ã¿ãªã³ã°ã§ããŸãããããã§ã¯é¢ä¿ãããŸããïŒïŒ
ããŒãžä»ãã䜿çšããåçŽãªããŒã¿ãã§ããïŒ
final selectedTab = useState(SelectedTab.Wallet);
final isDrawerOpen = useValueNotifier(false);
final pageNo = useValueNotifier(0);
final generalData = useValueNotifier(initialData);
final services = useXApi();
final isLoading = useValueNotifier(false);
final waybillData = useValueNotifier<List<WaybillResponseModel>>([]);
final theme = useTheme();
final router = useRouter();
fetchNextPage() async {
if (isLoading.value || selectedTab.value != SelectedTab.Wallet) return;
isLoading.value = true;
final request = WaybillRequestModel()..pageNo = pageNo.value;
final result = await services.waybillGetList(model: request);
if (result.isOk && result.data.length > 0) {
pageNo.value += 1;
waybillData.value = [...waybillData.value, ...result.data];
}
isLoading.value = false;
}
// first fetch
useEffect(() {
fetchNextPage();
return () {};
}, []);
ãã©ãŒã ããžãã¯ïŒé»è©±çªå·ã®ç¢ºèªãšã¿ã€ããŒã®åéä¿¡ã䌎ããã°ã€ã³ãã©ãŒã ïŒïŒ
final theme = useTheme();
final loginState = useValueNotifier(LoginState.EnteringNumber);
final error = useValueNotifier<String>(null);
final phoneNumberController = useTextEditingController(text: "");
final phoneNumberFocusNode = useMemoized(() => FocusNode(), []);
final otpFocusNode = useMemoized(() => FocusNode(), []);
final otpController = useTextEditingController(text: "");
final appState = Provider.of<AppStateController>(context);
final services = useXApi();
final router = useRouter();
final resendTimerValue = useValueNotifier(0);
useEffect(() {
var timer = Timer.periodic(Duration(seconds: 1), (t) async {
if (resendTimerValue.value > 0) resendTimerValue.value--;
});
return () => timer.cancel();
}, []);
final doLogin = () async {
// login
loginState.value = LoginState.LoggingIn;
final loginResult = await services.authLoginOrRegister(
mobileNumber: phoneNumberController.text,
);
if (loginResult.isOk) {
loginState.value = LoginState.EnteringOtpCode;
WidgetsBinding.instance.addPostFrameCallback((_) {
FocusScope.of(context).requestFocus(otpFocusNode);
});
resendTimerValue.value = 30;
} else {
error.value = loginResult.errorMessage;
loginState.value = LoginState.EnteringNumber;
WidgetsBinding.instance.addPostFrameCallback((_) {
FocusScope.of(context).requestFocus(phoneNumberFocusNode);
});
}
};
ã¢ãã¡ãŒã·ã§ã³ã«ã€ããŠã¯ã @ rrousselGitããã§ã«ååãªäŸãæäŸããŠãããšæããŸãã
ããã¯ã®æ§æå¯èœãªæ§è³ªã«ãããäžèšã®ã³ãŒãã®ãªãã¡ã¯ã¿ãªã³ã°ãã¯ããã«ç°¡åã§ãåå©çšå¯èœã§ãã¯ãªãŒã³ã«ãªãæ¹æ³ã«ã€ããŠã¯èª¬æããããããŸããããå¿ èŠã«å¿ããŠããªãã¡ã¯ã¿ãªã³ã°ãããããŒãžã§ã³ãæçš¿ããããšãã§ããŸãã
äœåºŠãè¿°ã¹ãããŠããããã«ããããŠRemiã®äžè«èª¿æ»ã§ããç°¡åã«èšãã°ã次ã®ããã«èšããŸãããã«ããŒã®åé·æ§ããã¹ããããã¯ããŒãžã£ãŒãªãã§ããã«ããŒã®æ©èœãå¿ èŠã§ãã ããã¯å®å šã«èŠçŽããŠããŸãããïŒ ããã«é²ãããã«ããã«ã³ãŒãäŸãå¿ èŠãªçç±ã¯å®å šã«æ··ä¹±ããŠããŸãã
RemiãæäŸããäŸã䜿çšããŠãåé·æ§ãæžããããã«ããŒã®ãã¹ããåé¿ããæ¹æ³ã®äŸãæåéãæäŸããŸããã
ç§ã¯åœŒã®ã³ãŒããèªåã®ã¢ããªã«è²Œãä»ããå®è¡ããŠæžãçŽããŸããã æ©èœæ§ã«é¢ããéããæçµçµæã¯ã»ãŒåãã§ãããã³ãŒãã«ã¯èŠä»¶ãä»å±ããŠããªãã£ããããã³ãŒããå®è¡ããã ãã§åéã§ããéãã§ãã 確ãã«ããšããžã±ãŒã¹ãšæœåšçãªåé¡ã«ã€ããŠè°è«ããããšã¯ã§ããŸããã代ããã«ããã¯ãªããããã¯ãšåŒã°ããŠããŸããã
åçŽãªãŠãŒã¹ã±ãŒã¹ã§ã¯Builderã䜿çšããè€éãªãŠãŒã¹ã±ãŒã¹ã§ã¯Builderã䜿çšããŸããã ããã§ã®è°è«ã¯ããã«ããŒã䜿çšããã«ãç°¡æœã§åå©çšå¯èœãªã³ãŒããæžãç°¡åãªæ¹æ³ã¯ãªããšããããšã§ãã æé»ã®ãã¡ã«ãããã¯ãã«ããŒãå¿ é ã§ãããFlutterã¢ããªãéçºããå¯äžã®æ¹æ³ã§ããããšãæå³ããŸãã ããã¯æããã«èª€ãã§ãã
ãããå®èšŒãããå®çšçãªæŠå¿µå®èšŒã³ãŒãã瀺ããŸããã ãã«ããŒãããã¯ã䜿çšããŠããŸããã§ããããŸãããã®ç¹å®ã®githubã®åé¡ã解決ããããšæããããç¡éã®åé¡ã»ãããã100ïŒ
ã«ããŒããŠããŸããã ããã¯ãªããããã¯ãšåŒã°ããŠããŸããã
ã¡ãªã¿ã«ãããã¯éåžžã«å¹ççã§ãããã³ãããŒã¯ããªããŠããBuilderãŠã£ãžã§ãããããåªããŠãããšæããŸãã ééã£ãŠããããšãå€æããå Žåã¯ãèããå€ããããšãã§ããŸããMobxãããã©ãŒãã³ã¹ã®ããã«ããã¯ã«ãªãããšãããã£ãå Žåã¯ãMobxãæšãŠãŠãããŒãããŒãã§ããã©ãã«ããŒã«åãæ¿ããŸãã
ããã¯ãœã³ã¯ã°ãŒã°ã«ã§åããŠããŸãã圌ã¯ããªãã«å¿è匷ããããŠç€Œåæ£ãããªããã°ãªãããããªãã®å©çŽã®æ¬ åŠã«ã€ããŠããªããåŒã¶ããšã¯ã§ããŸããã 圌ãã§ããæåã®ããšã¯ãããå€ãã®äŸãæšãé²ããããšã§ãã
ç§ã¯èª°ã«ãååãåŒãã ããå人çãªæ»æãå ãããããŸããã§ããã ç§ã¯ããã«æ瀺ãããè°è«ã«ã®ã¿åå¿ããç§ã®æèŠãå
±æããŸãã
ïŒç§ãç¥ã£ãŠããããšã¯äººæ°ããªããå°æ°æŽŸã§ãïŒãããŠå®éã®åäŸãã³ãŒãã§æ瀺ããããšããããŸããã ç§ã¯ãã£ââãšå€ãã®ããšãã§ããŸããç§ã®äŸãã©ãã«è¶³ããªãã®ãã話ãåããããããæ¹åããæ¹æ³ãèŠãŠãããããšæããŸãããããããªããããã¯ãšåŒã°ããããšã¯äžçš®ã®äžå¿«æã§ãã
ããããçŠæ¢ããã以å€ã«å€±ããã®ã¯äœããªãã®ã§ãç§ã¯ããªããåŒã¶ããšãæ¬åœã«æ°ã«ããŸããã
çµéšããåé¡ã®è§£æ±ºçã¯ããã¯ã ãã§ããïŒãReactããããè¡ããããïŒã代æ¿æ¡ãæ³åããŠãããç¡éã®åé¡ã»ãããã100ïŒ
æºãããŠããªãéãã2人ããããã»ããã«ãªã£ãŠããããšã¯æããã§ããããªããåŸäºããããšãæ€èšããŸããã
ããã¯åççã§ã¯ãªããçã«é¢äžããããšãã欲æ±ã®æ¬ åŠã瀺ããŠããŸãã
ãã¡ãããäžèšã®ãã¹ãŠã¯ãç§ã®æèŠã§ããã
ãã®äŸã§ã¯ããã¯ã®æçšæ§ãããããŸãããäžåºŠã«å€ãã®ãªããžã§ã¯ããåæåãããããã«èŠããç§ã®å Žåããã®å Žåã¯AnimationController
sã§ããããã©ã®ããã«æ©èœããã®ãç解ã§ããªããšæããŸããå®éã«ã¯äœã§ãããŸããŸããã ããã¯ã¯ãã®ã±ãŒã¹ãã©ã®ããã«åŠçããŸããïŒ
åºæ¬çã«ãããåãããã¯ã®æ¹æ³ã¯ãããŸãã
var x1 = useState(1);
var x2 = useState(2);
var x3 = useState(3);
ã®äžãž
var xs = []
for (int i = 0; i < 3; i++)
xs[i] = useState(i);
ããã¯ã«ãŒã«ã«éåããã«ïŒ éåžžã®Flutterã«åçã®ãã®ããªã¹ãããããã§ãã ç§ã¯Flutterã®ããã¯ã®çµéšãããŸããªãã®ã§ãããã§ææ ¢ããŠãã ããã
ãã¹ãŠã®initStateã䜿çšããŠãªã³ããã³ãã§ããã¯ãªããžã§ã¯ãïŒAnimationControllersãªã©ïŒã®é åãäœæããæ¢ã«ã€ã³ã¹ã¿ã³ã¹åãããç¶æ ã§ç Žæ£ãããã®ã§ãããããã¯ã§ã©ã®ããã«æ©èœãããããããŸããã
@satvikpendemã¯ãã¯ã©ã¹ã®ããããã£ã®ãããªããã¯ã«ã€ããŠèããŸãã ããããã«ãŒãã§å®çŸ©ããŸããããããšãæåã§1ã€ãã€ååãä»ããŸããïŒ
ããªãã®äŸã§ã¯ããã®ããã«å®çŸ©ããŠããŸã
var x1 = useState(1);
var x2 = useState(2);
var x3 = useState(3);
ãã®ãŠãŒã¹ã±ãŒã¹ã«åœ¹ç«ã¡ãŸãïŒ
var isLoading = useState(1);
var selectedTab = useState(2);
var username = useState(3); // text field
åuseState
ãç¶æ
ããžãã¯ã®ååä»ãéšåã«ã©ã®ããã«é¢é£ããŠãããããããŸããïŒ ïŒisLoadingã®useStateã¯ãã¢ããªãèªã¿èŸŒã¿ç¶æ
ã®ãšãã«æ¥ç¶ãããŸãïŒ
2çªç®ã®ã¹ããããã§ã¯ãã«ãŒãã§useState
ãåŒã³åºããŠããŸãã useState
ã¯ãç¶æ
ããžãã¯ã®äžéšã§ã¯ãªããå€ã®ææè
ãšããŠèããŠããŸãã ãã®ãªã¹ãã¯ã ListView
ã®ã¢ã€ãã ã®æã衚瀺ããããã«å¿
èŠã§ããïŒ ã¯ãã®å Žåããªã¹ãå
ã®ãã¹ãŠã®é
ç®ãåå¥ã§ã¯ãªãç¶æ
ãšèŠãªãå¿
èŠããããŸãã
final listData = useState([]);
ããã¯useState
ããã ãã®ãã®ã§ãããæ¡ä»¶ãŸãã¯ã«ãŒãã§ããã€ãã®ããã¯ãåŒã³åºãããã®ããã€ãã®ãŠãŒã¹ã±ãŒã¹ïŒéåžžã«ãŸãã ãšæããŸãïŒãèŠãããšãã§ããŸãã ãããã®çš®é¡ã®ããã¯ã«ã¯ãããŒã¿ã®ãªã¹ããåŠçããããã®1ã€ã§ã¯ãªãå¥ã®ããã¯ãå¿
èŠã§ãã äŸãã°ïŒ
var single = useTest("data");
var list = useTests(["data1", "data2"]);
// which is equivalent to
var single1 = useTest("data1");
var single2 = useTest("data2");
ãªãã»ã©ãããã¯ã䜿çšãããšãè€æ°ã®AnimationControllerãªã©ã®ã¢ã€ãã ã®é åãæã€ã±ãŒã¹ãåŠçããããã«å¥ã®ããã¯ãäœæããå¿ èŠãããããã«èŠããŸãã
ããã¯ç§ãæåã«æã£ãŠãããã®ã§ãæ©èœããŠããªãããã§ãïŒ
final animationControllers = useState<List<AnimationController>>([]);
animationControllers.value = List<AnimationController>.generate(
50,
(_) => useAnimationController(),
);
ããããè€æ°ã®ã¢ã€ãã ãåŠçããããã«ç¬èªã®ããã¯ãäœæããå Žåãããã¯æ©èœããã¯ãã§ãããïŒ
class _MultipleAnimationControllerHook extends Hook<MultipleAnimationController> {
const _MultipleAnimationControllerHook({
this.numControllers,
this.duration,
this.debugLabel,
this.initialValue,
this.lowerBound,
this.upperBound,
this.vsync,
this.animationBehavior,
List<Object> keys,
}) : super(keys: keys);
/// Take in number of controllers wanted
/// This hook assumes all `AnimationController`s will have the same parameters
final int numControllers;
final Duration duration;
final String debugLabel;
final double initialValue;
final double lowerBound;
final double upperBound;
final TickerProvider vsync;
final AnimationBehavior animationBehavior;
<strong i="10">@override</strong>
_AnimationControllerHookState createState() =>
_AnimationControllerHookState();
}
class _AnimationControllerHookState
extends HookState<AnimationController, _AnimationControllerHook> {
List<AnimationController> _multipleAnimationController; // return a list instead of a singular item
<strong i="11">@override</strong>
void initHook() {
super.initHook();
for (int i = 0; i < hook.numControllers) // just added loops
_multipleAnimationController[i] = AnimationController(
vsync: hook.vsync,
duration: hook.duration,
debugLabel: hook.debugLabel,
lowerBound: hook.lowerBound,
upperBound: hook.upperBound,
animationBehavior: hook.animationBehavior,
value: hook.initialValue,
);
}
<strong i="12">@override</strong>
void didUpdateHook(_AnimationControllerHook oldHook) {
for (int i = 0; i < numControllers; i++) {
if (hook.vsync != oldHook[i].vsync) {
_multipleAnimationController[i].resync(hook.vsync);
}
if (hook.duration != oldHook[i].duration) {
_multipleAnimationController[i].duration = hook.duration;
}
}
}
<strong i="13">@override</strong>
MultipleAnimationController build(BuildContext context) {
return _multipleAnimationController;
}
<strong i="14">@override</strong>
void dispose() {
_multipleAnimationController.map((e) => e.dispose());
}
}
ããã¯ãããã¯ã®åäžããŒãžã§ã³ãããå Žåããããè€æ°ã®ã¢ã€ãã ãæã€ããŒãžã§ã³ã«äœ¿çšã§ããã代ããã«ããžãã¯ãæžãçŽãå¿ èŠãããããšãæå³ããŸããïŒ ãããšãããããè¡ãããã®ããè¯ãæ¹æ³ã¯ãããŸããïŒ
誰ããç§ãç¥ãããããã¯ä»¥å€ã®äŸãæãããã®ãªããç§ã¯åå©çšæ§ããºã«ã®ãã®ããŒã¹ã«ã€ããŠçåã«æã£ãŠããŸããã ãã®åäœãç¬èªã®AnimationControllerãã£ãŒã«ããæã€ã¯ã©ã¹ã«ã«ãã»ã«åããæ¹æ³ããããããããŸãããããããã«ãŒãå ã§äœæãããå Žåãããã¯ãã«ãŒã«ã«éåããŸãã ãããããããã¯å®è£ ã®æ¡ä»¶ãã«ãŒãã®åœ±é¿ãåããªãVueãã©ã®ããã«ãããè¡ãããèããããšãã§ããŸãã
@satvikpendem
ç§ã®ã¹ããŒãã¡ã³ãã¯AnimationController
ãŸãã¯useAnimationController
ã¯æå¹ã§ã¯ãªããšæããŸã
è€æ°ã®AnimationController
ãããå Žåã§ããã¯ã©ã¹ã¡ãœããã§äœ¿çšããããã«å¿
ãããé
åã«æ ŒçŽããå¿
èŠã¯ãªãããã§ãã äŸãã°ïŒ
useSingleTickProvider();
final animation1 = useAnimationController();
final animation2 = useAnimationController();
final animation3 = useAnimationController();
// ...
useEffect(() async {
await animation1.forward();
await Future.sleep(100);
await animation1.reverse();
await animation2.forward();
await animation3.forward();
}, []);
ïŒãªã¹ããäœæããŠanimation[0]
ããã«åç
§ããããšã¯ãããŸããïŒ
æ£çŽãªãšãããããã¯ã䜿ã£ãåå¿ãšãã©ãã¿ãŒã®çµéšã§ã¯ãã«ãŒãå ã§ããçš®ã®ããã¯ãåŒã³åºãå¿ èŠã¯ãã£ãã«ãããŸããã§ããã ããã§ãããœãªã¥ãŒã·ã§ã³ã¯åçŽæå¿«ã§å®è£ ãç°¡åã§ããã ä»èããŠã¿ããšãIMOããããã¯ãªãŒã³ãªããœãªã¥ãŒã·ã§ã³ã§ããã³ã³ããŒãã³ãïŒãŠã£ãžã§ããïŒãããããã«äœæãããªã©ãããè¯ãæ¹æ³ã§ç¢ºå®ã«è§£æ±ºã§ããå¯èœæ§ããããŸãã
è€æ°ã®AnimationController
ãåŠçããç°¡åãªæ¹æ³ãããå Žåã¯ã質åã«çããããã«ãã¯ãããããŸãã
final ticker = useTickerProvider();
final controllers = useMemo(() => [AnimationController(ticker), AnimationController(ticker)], []);
useEffect(() {
controllers.forEach(x => x.resync(ticker));
return () => controllers.forEach(x => x.dispose());
}, [ticker, controllers]);
AnimationController
ãåçã§ããå Žåã¯ã useState
䜿çšããããšãã§ããŸããïŒãã£ãã«ãŒãå€æŽããããšãã«ãååæãããŸãïŒ
@rrousselGitè€æ°ã®ããã¯ãããäŸãæããŠ
List<AnimationController> controllers = []; int numAnimationControllers = 50; <strong i="8">@override</strong> void initState() { for (int i = 0; i < numAnimationControllers; i++) controllers.add(AnimationController(...)); } <strong i="9">@override</strong> void dispose() { for (int i = 0; i < numAnimationControllers; i++) controllers[i].dispose(); }
ããããããã¯ã䜿çšãããšãã«ãŒãå ã§
useAnimationController
ãåŒã³åºãããšã¯ã§ããŸããã ããã¯äºçŽ°ãªäŸã ãšæããŸããããã®ã¿ã€ãã®ãŠãŒã¹ã±ãŒã¹ã®è§£æ±ºçã¯ã©ãã«ãèŠã€ãããŸããã§ããã
ããã¯ã¯ãããå¥ã®æ¹æ³ã§è¡ããŸãã
ã³ã³ãããŒã©ã®ãªã¹ãã¯ããäœæããŸããããã³ã³ãããŒã©ããžãã¯ã次ã®é ç®ã«ç§»åããŸãã
Widget build(context) {
return ListView(
children: [
for (var i = 0; i < 50; i++)
HookBuilder(
builder: (context) {
final controller = useAnimationController();
},
),
],
);
}
ãŸã 50åã®ã¢ãã¡ãŒã·ã§ã³ã³ã³ãããŒã©ãŒãäœæããŸãããããããã¯å¥ã®ãŠã£ãžã§ããã«ãã£ãŠææãããŠããŸãã
ãªããããå¿ èŠãªã®ããšããäŸãå ±æããŠãããã¯ã«å€æããŠãã£ã ã®ãªããžããªã«è¿œå ããããšãã§ããŸããïŒ
ããã¯ãœã³ã¯ã°ãŒã°ã«ã§åããŠããŸãã圌ã¯ããªãã«å¿è匷ããããŠç€Œåæ£ãããªããã°ãªãããããªãã®å©çŽã®æ¬ åŠã«ã€ããŠããªããåŒã¶ããšã¯ã§ããŸããã 圌ãã§ããæåã®ããšã¯ãããå€ãã®äŸãæšãé²ããããšã§ãã
@Hixie ããããããªãã®æ°æã¡ãªããããèšã£ãŠãã ããïŒããã§ããŸãã¯ç§ã«å人çã«é£çµ¡ããŠãã ããïŒã
RemiãæäŸããäŸã䜿çšããŠãåé·æ§ãæžããããã«ããŒã®ãã¹ããåé¿ããæ¹æ³ã®äŸãæåéãæäŸããŸããã
æè¬ããŸããããã®ããžãã¯ãããŸããŸãªãŠãŒã¹ã±ãŒã¹ã«é©çšãããšãã«ããã®ã³ãŒãããå ±éã®ãã¿ãŒã³ãæœåºããæ¹æ³ãããããŸããã
OPã§ãç§ã¯çŸåšã3ã€ã®éžæè¢ããããšè¿°ã¹ãŸããã
StreamBuilder
ãšãã®AsyncSnapshot
ã¯è€éãªç¶æ
ããžãã¯ã§ãããšäž»åŒµããŸãïŒã3çªç®ã®éžæè¢ïŒ Property
ãŸãã¯addDispose
ããããŒã¶ã«ã®åæã®å埩ãšåãã«ããŽãªã«ãããŸãïŒã䜿çšããããã«èŠããŸãã
以åããã¿ãŒã³ãå€æããããã®è©äŸ¡ã°ãªãããäœæããŸããã
ããã§ããªã¢ã³ããå®è¡ã§ããŸããïŒ ç¹ã«ãè€æ°å䜿çšããå Žåã«ã³ãŒããéè€ãããã«StreamBuilder
ãã¹ãŠã®æ©èœãå®è£
ãã®ãã°ã«é¢ãããã®æç¹ã§ã®ç§ã®èšç»ã¯æ¬¡ã®ãšããã§ãã
誰ãããããã®ãããããæäŒãããã®ãªããç§ã¯ééããªãå©ããŠãããŠããããã§ãã ç§ã¯æåã«NNBD移è¡ã«åãçµãã§ããã®ã§ãããã«ããã«å°éããå¯èœæ§ã¯äœãã§ãã
@rrousselGit確ãã«ãç§ã¯å€ãã®ãŠã£ãžã§ãããç»é¢äžã移åã§ããã¢ããªãäœæããŠããŸãïŒ Box
esãšåŒã³ãŸãããïŒããŠã£ãžã§ããã¯äºãã«ç¬ç«ããŠç§»åã§ããå¿
èŠããããŸãïŒå°ãªããšãããŠã£ãžã§ãããå¿
èŠã§ãïŒã Box
ããšã«1ã€ã®AnimationControllerïŒã ããã¯ãè€æ°ã®ãŠã£ãžã§ããéã§å
±æããã1ã€ã®AnimationControllerã ãã§äœæãã1ã€ã®ããŒãžã§ã³ã§ãããå°æ¥çã«ã¯ãã«ã¹ã¿ã ã¹ã¯ããŒã«ãã€ãŒã«å¹æã䜿çšããŠCupertinoPicker
ãå®è£
ãããªã©ã®è€éãªå€æãè¡ãããã«ãåãŠã£ãžã§ãããåå¥ã«ã¢ãã¡ãŒã·ã§ã³åããå¯èœæ§ããããŸãã ã
ã¹ã¿ãã¯ã«ã¯ãFloatingActionButtonãã¯ãªãã¯ãããšäžäžã«ç§»åãã3ã€ã®ããã¯ã¹ããããŸãã
import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';
void main(List<String> args) => runApp(const App());
class App extends HookWidget {
const App({Key key});
static const Duration duration = Duration(milliseconds: 500);
static const Curve curve = Curves.easeOutBack;
<strong i="11">@override</strong>
Widget build(BuildContext context) {
final AnimationController controller =
useAnimationController(duration: duration);
final Animation<double> animation = Tween<double>(
begin: 0,
end: 300,
)
.chain(
CurveTween(
curve: curve,
),
)
.animate(controller);
final ValueNotifier<bool> isDown = useState<bool>(false);
final ValueNotifier<int> numBoxes = useState<int>(3);
return MaterialApp(
home: SafeArea(
child: Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () {
if (!isDown.value) {
controller.forward();
isDown.value = true;
} else {
controller.reverse();
isDown.value = false;
}
},
),
body: AnimatedBuilder(
animation: animation,
builder: (_, __) => Boxes(
numBoxes: numBoxes.value,
animation: animation,
),
),
),
),
);
}
}
class Boxes extends StatelessWidget {
Boxes({
<strong i="12">@required</strong> this.numBoxes,
<strong i="13">@required</strong> this.animation,
});
final int numBoxes;
final Animation<double> animation;
<strong i="14">@override</strong>
Widget build(BuildContext context) {
return Stack(
children: List<Widget>.generate(
numBoxes,
(int index) => Positioned(
top: (animation.value) + (index * (100 + 10)),
left: (MediaQuery.of(context).size.width - 100) / 2,
child: Container(
width: 100,
height: 100,
color: Colors.blue,
),
),
),
// ],
);
}
}
ãã®å Žåãåããã¯ã¹ã¯äžæã«ç§»åããŸãããããšãã°äžŠã¹æ¿ãé¢æ°ã®èŠèŠåãäœæããããã¢ãã¡ãŒã·ã§ã³ãªã¹ãå
ã®èŠçŽ ã移åããããããªã©ãããè€éãªã·ããªãªãæ³åã§ããŸãããã®å Žåã芪ãŠã£ãžã§ããã¯åBox
å Žæã«é¢ããããŒã¿ãèªèããŸãã
åé¡ã¯ãAnimationControllerãšãããã䜿çšããŠåããé§åããBox
ãåãã¯ã©ã¹ã«ãªãããã䜿çšããé
åãä¿æããŠAnimationControllerãééããå¿
èŠãããããšã§ãããã«ããŒããŸãã¯åBox
ç¬èªã®AnimationControllerãç¶æãããŸãã
ããã¯ã䜿çšããŠã Box
ãšèŠªãŠã£ãžã§ãããåãã¯ã©ã¹ã«ãªãå ŽåãåBox
ãAnimationControllerã§æž¡ãããæåã®ã±ãŒã¹ã®AnimationControllerã®ãªã¹ããäœæããã«ã¯ã©ãããã°ããã§ããïŒ äžèšã®HookBuilderã§ã®åçã«åºã¥ããšãããã¯å¿
èŠãªãããã§ãããããªããèšãããã«ç¶æ
ãåãŠã£ãžã§ããã«ç§»åããåBox
useAnimationController
ä»ããŠç¬èªã®AnimationControllerãæãããããšãéžæããå Žåãå¥ã®åé¡ãçºçããŸãããäœæããAnimationControllerã芪ã¯ã©ã¹ã«å
¬éããŠãååã®ç¬ç«ããã¢ãã¡ãŒã·ã§ã³ã調æŽããã³å®è¡ããã«ã¯ã©ãããã°ããã§ããïŒ
Vueã§ã¯emit
ãã¿ãŒã³ãä»ããŠèŠªã«ã€ãã³ããè¿ãããšãã§ããã®ã§ãFlutterã§ã¯ã芪ãã°ããŒãã«ç¶æ
ãæŽæ°ããåãã°ããŒãã«ããªãã¹ã³ããRiverpodãRxãªã©ã®ããé«åºŠãªç¶æ
管çãœãªã¥ãŒã·ã§ã³ãå¿
èŠã§ããïŒå·ïŒ å°ãªããšããã®ãããªç°¡åãªäŸã§ã¯ããã¹ãã§ã¯ãªãããã§ãã æ··ä¹±ã解æ¶ããŠãããŠããããšãã
@satvikpendemç³ãèš³ãããŸããããã¯ã£ããããŸããã§ããã ããã¯ã§ãããã¯ããŠããåé¡ã§ã¯ãªããããã¯ãªãã§ãããè¡ãæ¹æ³ã瀺ããŠããã ããŸããïŒ
è¡ãè©°ãŸã£ãŠããå Žæã§ã¯ãªããäœãããããšããŠããã®ããæ確ã«ç解ããã
ããããç°¡åã«æšæž¬ãããšã代ããã«ééæ²ç·ãæ¢ããŠããŠãåäžã®ã¢ãã¡ãŒã·ã§ã³ã³ã³ãããŒã©ãŒããããšæããŸãã
@rrousselGit確ãã«ãããã«ãããŸã
import 'package:flutter/material.dart';
void main(List<String> args) => runApp(const App());
class Animator {
Animator({this.controller, this.animation});
AnimationController controller;
Animation<double> animation;
}
class App extends StatefulWidget {
const App({Key key});
static const Duration duration = Duration(milliseconds: 500);
static const Curve curve = Curves.easeOutBack;
<strong i="7">@override</strong>
_AppState createState() => _AppState();
}
class _AppState extends State<App> with TickerProviderStateMixin {
List<Animator> animators = [];
bool isDown = false;
int numBoxes = 3;
<strong i="8">@override</strong>
void initState() {
for (int i = 0; i < numBoxes; i++) {
final AnimationController c = AnimationController(
duration: App.duration,
vsync: this,
);
animators.add(
Animator(
controller: c,
animation: Tween<double>(
begin: 0,
end: 300,
)
.chain(
CurveTween(
curve: App.curve,
),
)
.animate(c),
),
);
}
super.initState();
}
<strong i="9">@override</strong>
void dispose() {
for (int i = 0; i < numBoxes; i++) {
animators[i].controller.dispose();
}
super.dispose();
}
<strong i="10">@override</strong>
Widget build(BuildContext context) {
return MaterialApp(
home: SafeArea(
child: Scaffold(
floatingActionButton: FloatingActionButton(
onPressed: () {
if (!isDown) {
for (final Animator animator in animators) {
animator.controller.forward();
}
setState(() {
isDown = true;
});
} else {
for (final Animator animator in animators) {
animator.controller.reverse();
}
setState(() {
isDown = false;
});
}
},
),
body: Stack(
children: List<Box>.generate(
numBoxes,
(int index) => Box(
index: index,
animation: animators[index].animation,
),
),
),
),
),
);
}
}
class Box extends StatelessWidget {
Box({
<strong i="11">@required</strong> this.animation,
<strong i="12">@required</strong> this.index,
});
final int index;
final Animation<double> animation;
<strong i="13">@override</strong>
Widget build(BuildContext context) {
return Positioned(
top: (animation.value) + (index * (100 + 10)),
left: (MediaQuery.of(context).size.width - 100) / 2,
child: Container(
width: 100,
height: 100,
color: Colors.blue,
),
);
}
}
å®éã«ã¯ããŠã£ãžã§ããããšã«1ã€ãã€ãè€æ°ã®ã¢ãã¡ãŒã·ã§ã³ã³ã³ãããŒã©ãŒãå¿ èŠã§ãããããã¯ãç¬èªã®ç¶ç¶æéãæ²ç·ãªã©ã䜿çšããŠãäºãã«ç¬ç«ããŠç§»åã§ããããã§ããäžèšã®ã³ãŒãã«ã¯ãç解ã§ããªããã°ãããããã§ãããããã«ã¢ãã¡ãŒã·ã§ã³åããå¿ èŠããããŸãããåºæ¬çã«ã¯ãã¿ã³ãã¯ãªãã¯ãããšäžäžã«3ã€ã®ããã¯ã¹ãã¢ãã¡ãŒã·ã§ã³åããå¿ èŠããããŸãã ãããããåãæ²ç·ãæã€ä»£ããã«ãããããã«ç°ãªãæ²ç·ãäžããããŸãã¯ãããããåã®ããã¯ã¹ãããé·ããŸãã¯çãæéã®100åã®ããã¯ã¹ãäœæããããŸãã¯å¶æ°ã®ããã¯ã¹ãäžããã·ããªãªãæ³åã§ããŸããå¥åŠãªãã®ã¯äžãããçã ã
éåžžã®Flutterã§ã¯ã initState
ãšdispose
äž¡æ¹ã«ã«ãŒããå«ããããšãã§ããŸãããããã¯ã䜿çšããŠããããã«ã¯èŠããªãã®ã§ãã©ãããã°ãããšæŠãããšãã§ããã®ã§ããããã ãŸãã Box
ã¯ã©ã¹ã芪ãŠã£ãžã§ããå
ã«é
眮ããããªãã®ã¯ãäž¡æ¹ãå³å¯ã«ã«ãã»ã«åããããªãããã§ãã 芪ããžãã¯ãåãã«ä¿ã€ããšãã§ããã¯ãã§ãããããšãã°Box
ãBox2
ãšäº€æããŸãã
ããããšãïŒ
ç§ã¯ããªãã®äŸã@TimWhitingã®ãªããžããªã«ããã·ã¥ããŸãããããã¯ã¯åçã§ãã
TL; DRãããã¯ïŒãŸãã¯ãã«ããŒïŒã䜿çšãããšãå¿ é ã§ã¯ãªã宣èšçã«èããããšãã§ããŸãã ãããã£ãŠã1ã€ã®ãŠã£ãžã§ããã«ã³ã³ãããŒã©ãŒã®ãªã¹ããé 眮ããã®ã§ã¯ãªããã³ã³ãããŒã©ãŒã匷å¶çã«é§åããŸããããã«ãããã³ã³ãããŒã©ãŒãã¢ã€ãã ã«ç§»åããæé»çãªã¢ãã¡ãŒã·ã§ã³ãå®è£ ãããŸãã
ããããšã@rrousselGitïŒ ããã¯ã䜿ãå§ããŠãã°ããã®éããã®ã¿ã€ãã®å®è£ ã«èŠåŽããŠããŸããããä»ã§ã¯ãããã©ã®ããã«æ©èœããããç解ããŠããŸãã äžã§è¿°ã¹ãããã«ãããã¯ããªã圹ç«ã€ã®ããç解ããã®ã«ãã£ãšèª¬åŸåããããããããªãã®ã§ãã¢ãã¡ãŒã·ã§ã³ã³ã³ãããŒã©ãŒããšã«ç°ãªãã¿ãŒã²ãããæã€ããŒãžã§ã³ã®PRãéãããšããã§ãã
ãããããåãæ²ç·ãæã€ä»£ããã«ãããããã«ç°ãªãæ²ç·ãäžããããŸãã¯ãããããåã®ããã¯ã¹ãããé·ããŸãã¯çãæéã®100åã®ããã¯ã¹ãäœæããããŸãã¯å¶æ°ã®ããã¯ã¹ãäžããã·ããªãªãæ³åã§ããŸããå¥åŠãªãã®ã¯äžãããçã ã
宣èšåãäœãããšããŠããã®ã§ããã didUpdateWidget/Hook
ã©ã€ããµã€ã¯ã«ã¡ãœãããããããªãã£ãã®ã§ãåã®å°éå
·ã芪ããå€ãã£ããšãã«ã¢ãã¡ãŒã·ã§ã³ãåããæ¹æ³ãããããŸããã§ãããããããããªãã®ã³ãŒãã¯ãããã¯ãªã¢ããŸããã
ä»æ¥ãç§ã®ã³ãŒãããŒã¹ã§å®éã®äŸã«åºããããã®ã§ããããå ±æããã»ãããããšæããŸããã
ãããã£ãŠããã®ã·ããªãªã§ã¯ãFirestoreã䜿çšããŠããŠãåStreamBuilderã§å®è¡ãããå®åæãããã®ã§ãç¬èªã®ã«ã¹ã¿ã ãã«ããŒãäœæããŸããã ValueListenableã䜿çšããå¿
èŠããããŸã
return ClipRRect(
borderRadius: BorderRadius.circular(CornerStyles.dialog),
child: Scaffold(
backgroundColor: state.theme.scaffoldBackgroundColor,
body: FamilyStreamBuilder<DocumentSnapshot>(
stream: state.listRef.snapshots(),
builder: (context, AsyncSnapshot<DocumentSnapshot> documentSnapshot) {
//When a list is updated, we need to update the listOrder
state.updateListOrderFromSnapshot(documentSnapshot);
return FamilyStreamBuilder<QuerySnapshot>(
stream: state.itemsCollection.snapshots(),
builder: (_, AsyncSnapshot<QuerySnapshot> itemsSnapshot) {
//Sort the list items by the idField on the list-doc
List<DocumentSnapshot> items = itemsSnapshot.data.documents;
state.handleDocsSync(items);
return ValueListenableBuilder(
valueListenable: state.listOrderNotifier,
builder: (_, List<String> listOrder, __) {
List<DocumentSnapshot> ordered = state.sortItems(items, listOrder);
//Set the firstCompleted item if we have one
state.firstCompletedItem = ordered
?.firstWhere((element) => element.data[FireParams.kIsComplete] == true, orElse: () => null)
?.documentID;
return _buildItemList(items, ordered);
},
);
});
},
),
),
);
次ã®ããã«æžãããšãã§ããã°ãæšè«ããã®ãã¯ããã«ç°¡åã«ãªãããã«æããŸãã
DocumentSnapshot list = useFamilyStream(state.listRef.snapshots());
List<DocumentSnapshot> items = useFamilyStream(state.itemsCollection.snapshots()).data.documents;
List<String> listOrder = useValueListenable(state.listOrderNotifier);
//When a list is updated, we need to update the listOrder
state.updateListOrderFromSnapshot(list);
//Sort the list items by the idField on the list-doc
state.handleDocsSync(items);
List<DocumentSnapshot> ordered = state.sortItems(items, listOrder);
//Set the firstCompleted item if we have one
state.firstCompletedItem = ordered
?.firstWhere((element) => element.data[FireParams.kIsComplete] == true, orElse: () => null)
?.documentID;
return ClipRRect(
borderRadius: BorderRadius.circular(CornerStyles.dialog),
child: Scaffold(
backgroundColor: state.theme.scaffoldBackgroundColor,
body: _buildItemList(items, ordered)
));
ããã«ããã詳现ãªåæ§ç¯ã«é¢ããæé©åã倱ãããŸããããã¹ãŠã®èŠèŠèŠçŽ ãæäžéšã®ãªãŒãããŒãã«ããããã¹ãŠã®ã©ãããŒãçŽç²ãªç¶æ ã§ãããããIRLã«éãã¯ãããŸããã
å€ãã®å®éã®ã·ããªãªãšåæ§ã«ãFirebaseã«ã¯Streamsãšããæ¥ç¶æ¹æ³ã1ã€ãããªãããããXã䜿çšããªãã§ãã ããããšããã¢ããã€ã¹ã¯çŸå®çã§ã¯ãããŸããããã®ãœã±ããã®ãããªåäœãå¿ èŠãªå Žåã¯ãã€ã§ãã¹ããªãŒã ã䜿çšããŸãã C'est lavieã
ããã«ããã詳现ãªåæ§ç¯ã«é¢ããæé©åã倱ãããŸããããã¹ãŠã®èŠèŠèŠçŽ ãæäžéšã®ãªãŒãããŒãã«ããããã¹ãŠã®ã©ãããŒãçŽç²ãªç¶æ ã§ãããããIRLã«éãã¯ãããŸããã
ããã§ãéãã¯ãããŸãã ããŒããèŠèŠçã§ãããã©ããã¯ãåæ§ç¯ã«è²»çšãããããã©ããã«ã¯åœ±é¿ããŸããã
ç§ã¯ãããããã®äŸãããŸããŸãªãŠã£ãžã§ããã«å解ããŸãïŒIDEã«ã¯ãããæ¬åœã«ç°¡åã«ããããã®ã¯ã³ã¯ãªãã¯ãªãã¡ã¯ã¿ãªã³ã°ããŒã«ããããŸãïŒã _buildItemList
ã¯ã FamilyStreamBuilder
ã«ãŒããšããéšåãšåæ§ã«ããããããŠã£ãžã§ããã§ããå¿
èŠããããŸãã
ãã现ããåæ§ç¯ãå®éã«å€±ãããšã¯ãããŸããã
å®éãããã¯ã¯useMemoized
ã䜿çšããŠãŠã£ãžã§ããã€ã³ã¹ã¿ã³ã¹ãç°¡åã«ãã£ãã·ã¥ã§ããããã«ããããšã§ããã®åŽé¢ãæ¹åããŸãã
ãããè¡ãTimã®ãªããžããªã«ã¯ããã€ãã®äŸããããŸãã
ç§ã¯ãããããã®äŸãããŸããŸãªãŠã£ãžã§ããã«å解ããŸãïŒIDEã«ã¯ãããæ¬åœã«ç°¡åã«ããããã®ã¯ã³ã¯ãªãã¯ãªãã¡ã¯ã¿ãªã³ã°ããŒã«ããããŸãïŒã
_buildItemList
ã¯ãFamilyStreamBuilder
ã«ãŒããšããéšåãšåæ§ã«ããããããŠã£ãžã§ããã§ããå¿ èŠããããŸãã
ãã®èŠ³ç¹ã§ã¯ããã©ãŒãã³ã¹ã®åé¡ã¯ãŸã£ãããªãã®ã§ãç§ã¯å®éã«ã¯ãããå®è¡ããããããŸããã ãããã£ãŠã100ïŒ ã®æéããã®ãããªãã€ã¯ãæé©åãããã³ãŒãã®å±ææ§ãšäžè²«æ§ãåªå ããŸãã ãã®ãã¥ãŒã¯ããŠãŒã¶ãŒãã¢ã¯ã·ã§ã³ãéå§ãããšãïŒãavgã10ç§ã«1åïŒããŸãã¯ããã¯ãšã³ãããŒã¿ãå€æŽãããéããŠãããªã¹ããèŠã€ããŠãããšãã«ã®ã¿åæ§ç¯ãããŸãïŒã»ãšãã©çºçããŸããïŒã ãŸããããã¯äž»ã«ãªã¹ãã§ããåçŽãªãã¥ãŒã§ããããªã¹ãã«ã¯å éšã§è¡ãããŠããç¬èªã®æé©åããããããããŸãã buildïŒïŒã¯æè¡çã«ã¯ãã€ã§ãèµ·åã§ããããšãç解ããŠããŸãããå®éã«ã¯ã©ã³ãã ãªåæ§ç¯ã¯éåžžã«ãŸãã§ãã
imoãã®ãã¹ãŠã®ããžãã¯ã1ã€ã®ãŠã£ãžã§ããã«ã°ã«ãŒãåãããŠãããšãäž»ã«å°æ¥æ»ã£ãŠãããšãã«ç§ã®ç掻ã楜ã«ããããã«ããã®ãã¥ãŒã®æäœãšãããã°ãéåžžã«ç°¡åã«ãªããŸã:)
ãã1ã€ã®æ³šæç¹ã¯ãç©Žã®3ã€ã®ã¯ããŒãžã£ãŒãš16ã®ã¹ããŒã¹ã®å åŽã«ããªãŒãæ§ç¯ãå§ããæ¹æ³ããªãã£ãããããã¹ãã¯åºæ¬çã«ãã«ãã¡ãœããããã匷å¶çã«å€ããããããšã§ãã
ã¯ããå¥ã®ãŠã£ãžã§ããã«ç§»åããã®ãçã«ããªã£ãŠãããšèšããŸãã ãããããªããã«ãã¡ãœããã«ãšã©ãŸããªãã®ã§ããïŒ ãã€ã©ãŒãã¬ãŒããå®éã«å¿ èŠãªãã®ã«æžããããšãã§ããã°ã2ã€ã®ãã¡ã€ã«ã«åå²ãããšããèªã¿ããããšã¡ã³ããã³ã¹ã®æéããããå¿ èŠã¯ãããŸããã ïŒããã©ãŒãã³ã¹ã¯åé¡ã§ã¯ãªããšä»®å®ããŸãããå€ãã®å Žåãåé¡ã§ã¯ãããŸããïŒ
ãã®ã·ããªãªã§ã¯ãStreamBuilderãåŠçããããã®ã«ã¹ã¿ã ãŠã£ãžã§ãããæ¢ã«äœæããããšãæãåºããŠãã ããã ä»ãç§ã¯ãããã®ãã«ããŒã®æ§æãåŠçããããã«å¥ã®ãã®ãäœãå¿ èŠããããŸããïŒ å°ãäžã«ããããã§ãã
ãã®ãã¥ãŒã§ã¯ããã©ãŒãã³ã¹ã®åé¡ã¯ãŸã£ãããªãããã§ã
ãããããã©ãŒãã³ã¹ã®ããã«ãŠã£ãžã§ããã«ãªãã¡ã¯ã¿ãªã³ã°ããã€ããã¯ãããŸããããã«ããŒã¯ãã§ã«ãããåŠçããå¿ èŠããããŸãã èªã¿ããããšåå©çšæ§ã®ããã«ãªãã¡ã¯ã¿ãªã³ã°ããŸãã ããããæ£ãããæ¹æ³ã ãšèšã£ãŠããã®ã§ã¯ãªããã³ãŒããã©ã®ããã«æ§é åããããèšã£ãŠããã ãã§ãã ãšã«ãããããã¯ããã«ãããã«ããããŸããã
ç©Žã®3ã€ã®ã¯ããŒãžã£ãŒãš16ã®ã¹ããŒã¹ã®äžã«ããªãŒãæ§ç¯ãå§ããããšã¯ã§ããŸããã§ãã
ç§ã¯ããªããããåºãã¢ãã¿ãŒãæã£ãŠãããããããŸãã...ïŒ-/
ããããã°ã2ã€ã®ãã¡ã€ã«ã«åå²ãããšããèªã¿ããããšã¡ã³ããã³ã¹ã®æéããããå¿ èŠã¯ãããŸããã
ãŠã£ãžã§ãããåããã¡ã€ã«FWIWã«é 眮ããŸãã
ãšã«ãããããã¯è¯ãäŸã§ãããããå€ãã®ãŠã£ãžã§ããã䜿çšããããããç°ãªãæ§æã§1ã€ã®ãŠã£ãžã§ããã䜿çšããæ¹ããããšæããŸãã
ç§ã¯ããªããããåºãã¢ãã¿ãŒãæã£ãŠãããããããŸãã...ïŒ-/
ç§ã¯è¶
ã¯ã€ãïŒDãæã£ãŠããŸãããdartfmtã¯æããã«ç§ãã¡å
šå¡ã80ã«å¶éããŠããŸãããããã£ãŠã16ã倱ãããšã¯éèŠã§ãã äž»ãªåé¡ã¯ãç§ã®å£°æã®çµããã§ããäœããå°ç¡ãã«ãªã£ããšãããã®},);});},),),);
ã¯æ¬åœã«é¢çœããããŸããã ãã®éå±€ãç·šéãããšãã¯åžžã«çŽ°å¿ã®æ³šæãæãå¿
èŠãããã swap with parent
ãããªäžè¬çãªIDEãã«ããŒã¯æ©èœããªããªããŸãã
ãŠã£ãžã§ãããåããã¡ã€ã«FWIWã«é 眮ããŸãã
100ïŒ ã§ããã1ã€ã®ãã¡ã€ã«ã§åçŽæ¹åã«ãžã£ã³ãããã®ã¯ç¶æãé£ããããšãããããŸããã ãã¡ããé¿ããããªãããšã§ãããå¯èœãªéãåæžãããç©äºããŸãšãããããã«åªããŠããŸãã
éèŠãªã®ã¯ãã¡ã€ã³ãªã¹ããç¬èªã®ãŠã£ãžã§ããã«ãªãã¡ã¯ã¿ãªã³ã°ãããšããŠãïŒç§ã¯åæããŸããããã¹ãããããã«ãã¡ãœãããããèªã¿ãããã§ãïŒã芪ãŠã£ãžã§ããã«ãã¹ãããªããŠãã¯ããã«èªã¿ããããªããŸãã å ¥ã£ãŠããã¹ãŠã®ããžãã¯ãäžç®ã§ç解ãã_MyListViewïŒïŒãŠã£ãžã§ãããã¯ã£ãããšèŠãŠãããã«ããã«é£ã³èŸŒãã§ãåšå²ã®ã³ã³ããã¹ããç解ããŠãããšç¢ºä¿¡ã§ããŸãã ãŸããæ¯èŒçç°¡åã«äŸåé¢ä¿ãè¿œå /åé€ã§ãããããæ¡åŒµæ§ãéåžžã«é«ããªããŸãã
dartfmtã¯æããã«ç§ãã¡å šå¡ã80ã«å¶éããŸã
ã€ãŸãããããç§ãäžè¬çã«dartfmtã䜿çšããªãçç±ã®1ã€ã§ããã䜿çšããå Žåã¯120æåãŸãã¯180æåã«èšå®ããŸã...
ããã§ã®ããªãã®çµéšã¯å®å šã«æå¹ã§ãã
ç§ãå®éã«ã¯ãäžæ¥äž120ã§ã:)ããããpub.devã¯ã80ã§ãã©ãŒããããããŠããªããã©ã°ã€ã³ãç©æ¥µçã«ããŠã³ã¬ãŒãããŠããããã®å€ãå€æŽãããšãç§ïŒç§ãã¡ïŒã¯å°æ°æŽŸã§ãããšããå°è±¡ãåããŸãã
ããã¯ã°ãããŠãããç§ãã¡ã¯ãããä¿®æ£ããå¿ èŠããããŸãã
pub.devã¯ãdartfmtãå°éããªããã©ã°ã€ã³ãããŠã³ã¬ãŒãããŸããã ã¹ã³ã¢ããŒãžã«ã³ã¡ã³ãã®ã¿ã衚瀺ãããŸãããã¹ã³ã¢ã¯åœ±é¿ãåããŸãã
ããããééããªããdartfmtã«ã¯è¡ã®é·ãã ãã§ãªãå€ãã®åé¡ããããŸãã
è¡ã®é·ããé·ããããšã次ã®ããã«ãè€æ°ã®è¡ã§èªã¿ããããªããåäžã®è¡ã«ãªããŸãã
object
..method()
..method2();
ããã¯æ¬¡ã®ããã«ãªããŸãã
object..method()..method2();
ç§ã¯ãããèŠãŠããŸããïŒ
åé¡ã®ããã±ãŒãžïŒ https ïŒ
èå³æ·±ãâãããã€ããŒããã°ããdartfmtã䜿çšããŠããªãã£ãããã以åã¯ééããªãããã§ã¯ãããŸããã§ããã
ç§ã¯æ£çŽã«ç«ã£ãŠããŸãã
ãããããã¯ééããªãæ°ããæ¯ãèãã§ããå»å¹Žã®æ¥ã«æåã«å ¬éãããšãããã¹ãŠã®ããã¯ã¹ã«ãã§ãã¯ããŒã¯ãä»ããŠããããšã確èªããŸãããdartfmtã¯å¿ èŠãããŸããã§ããã
ããããã¹ãŠã®è°è«ã®åŸããã©ãã¿ãŒã®ããã¯ã®ãããªãœãªã¥ãŒã·ã§ã³ã®ãã€ãã£ããµããŒããèŠãããããšãé¡ã£ãŠããŸãã useHook
ãŸãã¯use Hook
ããããããŸãã¯ãã©ãã¿ãŒããŒã ãèªåãã¡ã®æ©èœãReactã®ããã§ã¯ãªããšæããããšãã§ãããã®ðð€·ââïž
final controller = useAnimationController(duration: Duration(milliseconds: 800));
ãããªæ¹æ³ã§ããã¯ã䜿çšããŸã
kotlin / swiftããã³ããŒãããDartsã®æ°ããããã°ã©ã æ©èœ_Extension_ã䜿çšããŠããã®æ§æãçŸããããã®ã¯è¯ãããšã§ã¯ãããŸãããïŒ
次ã®ãããªãã®ïŒ final controller = AnimationController.use(duration: Duration(milliseconds: 800));
ãã®ã¢ãããŒãã§ã¯ãflutter / dartããŒã ãçŸåšå©çšå¯èœãªæ§æuseHook
代ããã«use Hook
ãè¿œå ããããšã決å®ããå Žåããã®æ¡åŒµé¢æ°ã«Annotation
ãèªã¿åã£ãŠã
final controller = use AnimationController(duration: Duration(milliseconds: 800));
ãŸãã const
ãnew
ããã«const
use
ããŒã¯ãŒãã䜿çšããããšã¯ç解ã§ã/æå³ããããŸãã
new Something
const Something
use Something
ãã®æšå¥šäºé
ã®ããŒãã¹ãšããŠãã³ã³ã¹ãã©ã¯ã¿ãŒ/ãžã§ãã¬ãŒã¿ãŒé¢æ°ã§ãããææ¡ãããAnnotation
ã䜿çš/å©çšã§ããããã«ãªããŸããã 次ã«ãããã€ãã®ã«ã¹ã¿ãã€ãºãè¡ã£ãdartã³ã³ãã€ã©ã¯ã use
ããŒã¯ãŒãããµããŒãããããã«å€æããŸãã
ãšãŠãçŸããããã©ãã¿ãŒ/ããŒãç¹æã®æ©èœð
https://github.com/TimWhiting/local_widget_state_approaches/tree/master/lib/statefulã®äŸãã人ã ã解決ãããåé¡ã代衚ããŠãããšä»®å®ããã®ã¯æ£ããã§ããïŒ
ä»ã®äººãã©ã®ããã«æããŠãããã¯ããããŸããããåé¡ã¯ããã«ããçšåºŠè¡šããŠãããšæããŸãïŒã€ãŸãã誰ããè¡šãããŠããªãããšãææããå¯èœæ§ãããããã確信ãæãŠãŸããïŒã
ç§ã¯ãã®ãªããžããªã§äžç«çãªè§£æ±ºçãè©Šã¿ãŸããã ããã¯ã®ããã«æ§æã§ããŸãããé¢æ°åŒã³åºãã®é åºãã«ãŒããªã©ã«äŸåããŸãããStatefulWidgetsãçŽæ¥äœ¿çšããŸãã ããã«ã¯ãããã¯ã¹ã€ã³ãšãããŒã«ãã£ãŠäžæã«èå¥ãããã¹ããŒããã«ããããã£ãå«ãŸããŸãã ç§ã¯ããã究極ã®è§£æ±ºçãšããŠå®£äŒããããšããŠããã®ã§ã¯ãªãã2ã€ã®ã¢ãããŒãã®äžéç¹ãšããŠå®£äŒããããšããŠããŸãã
ç§ã¯ãããlifecycleMixinã¢ãããŒããšåŒãã§ããŸããããã¯ãããã§èª¬æããLatePropertyã¢ãããŒãã«éåžžã«è¿ããã®ã§ãããäž»ãªéãã¯ãããå€ãã®ã©ã€ããµã€ã¯ã«ãå®è£ ãããŠãããç°¡åã«æ§æã§ããããšã§ãã ïŒã©ã€ããµã€ã¯ã«ã®éšåã§ã¯ãinitState以å€ã®ãŠã£ãžã§ããã©ã€ããµã€ã¯ã«ã䜿çšããŠããªããããå€ãã®åŠçãè¡ã£ãŠããªããããå®å šã«æ··ä¹±ããŠããå¯èœæ§ããããŸãïŒã
ç§ã¯ãã®ã¢ãããŒãã奜ãã§ãïŒ
次ã®çç±ããããã®ã¢ãããŒãã¯ïŒããã¯ãšæ¯èŒããŠïŒå¥œãã§ã¯ãããŸããã
ç°¡åãªåäŸã
ã¢ãã¡ãŒã·ã§ã³ã«ãŠã³ã¿ãŒã®äŸ
ãã¬ãŒã ã¯ãŒã¯
åå©çšå¯èœãªç¶æ
æ§æããžãã¯ã®å
±éããã
ã©ãã ãã®æéããã£ããããããŸãããã倧åŠé¢ã®å匷ã§ãã€ãå¿ããããŠããŸããããã£ãŒãããã¯ããåŸ ã¡ããŠããŸãã @rrousselGitããã¯ããã¯ã«ã©ãã ãè¿ãã§ãããåå©çšæ§ãŸãã¯æ§æå¯èœæ§ã«ããã€ãã®æãããªç©ŽããããŸããïŒ
ç§ã¯èªåã®è§£æ±ºçã宣äŒããããšã¯ããŠããŸããããäžç«çãªç«å Žã§ååããªè°è«ã奚å±ããŠããŸãã äœãæ¬ ããŠããã®ãããã®è§£æ±ºçãç§ãã¡ã«äœãããããã®ãã«ã€ããŠåæã§ããã°ãç§ãã¡ã¯é 調ã«åé²ãããšæããŸãã
@TimWhitingãã®ã¢ãããŒãã§ç§ãæ±ããŠããäž»ãªåé¡ã¯ãå ç¢æ§ã®æ¬ åŠã§ãã ããã§ã®å€§ããªæšé²åã¯ãç°¡æœãªåœ¢ã§ã®ãã«ããŒã®ä¿¡é Œæ§ã®å¿ èŠæ§ã§ãã éæ³ã®IDãšã©ã€ããµã€ã¯ã«ã§è¡çªããæ©èœã®äž¡æ¹ãããã°ãçºçããããã®æ°ãããã¯ãã«ãäœæããŸããèªãã®ãããªãåä»ã§ããã«ãããããããå°ãªããšã100ã§ããããšãããã£ãŠããã®ã§ããã«ããŒã䜿çšããããšãããŒã ã«æšå¥šãç¶ããŸãã ïŒ ãã°ããªãŒã
äŸã«é¢ããŠã¯ããŠã£ãžã§ããã«é¢é£ä»ããããæéå€ã䜿çšããŠãAnimationControllerã䜿çšããã®ãå®ç§ãªäŸã ãšæããŸãã ã·ã³ãã«ã§èŠªãã¿ããããã®ã«ããŸãã ãã以äžã«é£è§£ã«ãªãå¿ èŠã¯ãããŸãããåå©çšå¯èœãªãã€ã©ãŒãã¬ãŒãã®å®ç§ãªå°ããªãŠãŒã¹ã±ãŒã¹ã§ãããã©ã€ããµã€ã¯ã«ããã¯ãå¿ èŠã§ãããã¹ãŠã®ãœãªã¥ãŒã·ã§ã³ã¯ãããã€ãã®ã¢ãã¡ãŒã·ã§ã³ãç°¡æœã«äœ¿çšã§ããããšã§ç°¡åã«å€æã§ããŸãã
ä»ã®ãã¹ãŠã¯ããããšåã䜿çšæ³ãã¹ããŒããã«ã³ã³ãããŒã©ãŒãã®ãŠãŒã¹ã±ãŒã¹ã®ããªãšãŒã·ã§ã³ã«ãããŸããã XãinitStateã§ãYãdisposeç¶æ ã§å®è¡ããäŸåé¢ä¿ãå€æŽããããšãã«ZãæŽæ°ããããšæããŸãã XãYãZãäœã§ãããã¯é¢ä¿ãããŸããã
@rrousselGitãããã§äœããã®æŽå¯ãæäŸã§ããã®ãããããšãçŸåšæã䜿çšãããŠããããã¯ã«é¢ããããŒã¿ãããã®ã ãããã 80ïŒ ã®ã¹ããªãŒã ãšã¢ãã¡ãŒã·ã§ã³ã ãšæããŸãããå®éã«äººã ãäœãæã䜿çšããŠããããç¥ã£ãŠãããšããã§ãããã
ããªãŒã®äžéšãåæ§ç¯ããããšã«é¢ããŠã¯ããã«ããŒã¯ãšã«ãããã®ã¿ã¹ã¯ã«èªç¶ã«é©ããŠããŸããç§ãã¡ã¯åœŒãã«ããããããã¹ãã§ãã ã¹ããŒããã«ã³ã³ãããŒã©ãŒã¯ãå¿ èŠã«å¿ããŠã¹ããŒãã¬ã¹ã¬ã³ãã©ãŒã«ç°¡åã«æ¥ç¶ã§ããŸãïŒãã¹ãŠã®Transitionã¯ã©ã¹ã«ããã«ã¡ã¯ïŒã
ç§ãã¡ããããããããªãã®ãšåãããã«ïŒ
var anim = get AnimationController();
return Column(
_someExpensiveBuildMethod(),
FadeTransition(opacity: anim, child: ...)
)
ç§ãã¡ã¯ãã€ã§ãã§ããïŒ
var foo = get ComplicatedThingController();
return Column(
_someExpensiveBuildMethod(),
ComplicatedThing(controller: foo, child: ...)
)
@esDotDevåæããŸããããŒãšãã«ããŒæ§æã¯ãlifecycleMixinã¢ãããŒãã®äž»ãªæ¬ ç¹ã§ãã ããã¯ã¹ã¿ã€ã«ã®ã¢ãããŒããšããã«é¢é£ããå¶éã䜿çšããããå€æ°å®£èšãç¶æ ã®ããããšã©ã€ããµã€ã¯ã«ã«é¢é£ä»ããããšãã§ããããã«ããèšèªã®å€æŽãé€ããŠããããåé¿ã§ãããã©ããã¯ããããŸããã ããããããè¯ã解決çãåŸãããªãéããããã¯ã䜿ãç¶ããä»ã®äººã«ã¹ããŒããã«ãŠã£ãžã§ããã䜿çšãããçç±ã§ãã ãã ããç¬èªã®å¶éã¯ãããŸãããããã¯ã®å¶éãæ°ã«å ¥ããªã人ã«ãšã£ãŠã¯èå³æ·±ãéžæè¢ã ãšæããŸãã
https://github.com/TimWhiting/local_widget_state_approaches/tree/master/lib/statefulã®äŸãã人ã ã解決ãããåé¡ã代衚ããŠãããšä»®å®ããã®ã¯æ£ããã§ããïŒ
æ£çŽããããããŸããã
ç§ã¯_ã¯ã_ãšèšããŸãã ããããããã¯æ¬åœã«ãããã®äŸãã©ã®ããã«è§£éãããã«äŸåããŸãã
ãã®ã¹ã¬ããã§ã¯ããäºããç解ããŠããªããšããæŽå²ãããã®ã§ããããäºåºŠãšèµ·ãããªãããšãä¿èšŒããããšã¯ã§ããŸããã
ãã®ãããã³ãŒãäŸã®äœ¿çšãå«ãã§ã代ããã«äžé£ã®ã«ãŒã«ãæœåºããããšãææ¡ããŸããã
äŸã¯äž»èŠ³çãªãã®ã§ãããè€æ°ã®è§£æ±ºçããããŸããããã®äžã«ã¯ããåºç¯ãªåé¡ã解決ã§ããªããã®ããããŸãã
@rrousselGitãããã§äœããã®æŽå¯ãæäŸã§ããã®ãããããšãçŸåšæã䜿çšãããŠããããã¯ã«é¢ããããŒã¿ãããã®ã ãããã 80ïŒ ã®ã¹ããªãŒã ãšã¢ãã¡ãŒã·ã§ã³ã ãšæããŸãããå®éã«äººã ãäœãæã䜿çšããŠããããç¥ã£ãŠãããšããã§ãããã
ãšãŠãå質ã ãšæããŸãã
ã©ã¡ãããšããã°ã useStream
ãšã¢ãã¡ãŒã·ã§ã³ã¯ããããæã䜿çšãããŠããŸããïŒ
context.watch
ã useBloc
ã useProvider
ã..ã䜿çšã§ããŸãTweenAnimationBuilder
ä»ã®æé»çã«ã¢ãã¡ãŒã·ã§ã³åããããŠã£ãžã§ãããããŒãºã®å€§éšåãã«ããŒããŸããuseImplicitlyAnimatedInt
ããã¯ãflutter_hooksã«è¿œå ãããšãç¶æ³ãå€ãããããããŸããã@esDotDevlifecycleMixinã¢ãããŒãã§ããŒ/ IDã®å¿ èŠæ§ãåé€ããŸããã ãã«ããŒã®æ§æã§ã¯ãŸã å°ãåä»ã§ãã ãããããããããããæçµçã«ã¯åœ¹ç«ã€å¯èœæ§ããããŸãã ç§ãçŽé¢ããŠããåé¡ã®1ã€ã¯ãåã·ã¹ãã ã«é¢ãããã®ã§ãã ããã¯ãæ©èœããŠããªãç¹å®ã®æ¹æ³ã§ç©äºããã£ã¹ãããããšããŸãã ãããããããã泚ææ·±ããã£ã¹ããŸãã¯åã·ã¹ãã ã®ç¿åŸãå¿ èŠã§ãã ã©ã€ããµã€ã¯ã«ã®æ··åã«é¢ããŠã¯ãã¢ã¯ã»ã¹ããããšããŠããç¹å®ã®ç¶æ ã«ãŠã£ãžã§ããã®ã©ã€ããµã€ã¯ã«ããã¢ã¯ã»ã¹ã§ããªãå Žåã«ãããã€ãã®åççãªäŸå€ãã¹ããŒããããšã§æ¹åã§ãããšæããŸãã ãŸãã¯ãã©ã€ããµã€ã¯ã«ãã«ããŒå ã§ãã«ããŒã®ã©ã€ããµã€ã¯ã«ã«ã®ã¿ã¢ã¯ã»ã¹ããå¿ èŠããããšãããªã³ãã
Remiã«æè¬ããŸããé©ããããšã«ã人ã ã¯Animationãé »ç¹ã«äœ¿çšããŠãã³ã¢å ã®TransitionãŠã£ãžã§ããã®å€§èŠæš¡ãªã³ã¬ã¯ã·ã§ã³ãé§åãããšæããŸãããã»ãšãã©ã®äººã¯ãèªã¿ãããããã¹ãããªããããããŸããŸãªImplicitã䜿çšããŠãããšæããŸãã ã
AnimatorControllerã¯ãæé»çãŠã£ãžã§ãããšæ瀺çãŠã£ãžã§ããã®ã¹ã€ãŒãã§éåžžã«ããŸãæ©èœããŸãããããã§ããç¶æ ãç¶æãããŠã£ãžã§ããã®ãã©ã¡ãŒã¿ãŒãšã©ã€ããµã€ã¯ã«ã«çµã³ä»ããå¿ èŠããããã®ã®åªããäŸã ãšæããŸãã ãããŠã解決ãã¹ãåé¡ã®å®ç§ãªå°ããªäŸãšããŠæ©èœããŸãïŒäºå®ã¯ã1ããŒã¹ã®ãŠã£ãžã§ããã®ããã«Flutterã§å®å šã«è§£æ±ºãããŸãïŒãããã¯ãã³ã³ãã³ãã§ã¯ãªãã¢ãŒããã¯ãã£ã«ã€ããŠè©±ãåããéäžããããšãã§ããŸãã
ããšãã°ã var anim = AnimationController.use(context, duration: widget.duration ?? _duration);
ã第äžçŽåžæ°ã§ããå Žåããããã®æé»çãŸãã¯æ瀺çãªã¢ãã¡ãŒã·ã§ã³ãå®éã«ååšããå¿
èŠããªãããšãèããŠã¿ãŠãã ããã ãããã¯ãã¹ãŠã³ã¢ã®åé¡ã管çããããã«äœæãããŠãããããåé·ã«ãªããŸãããŠã£ãžã§ããã®ã³ã³ããã¹ãå
ã§ã¹ããŒããã«ãªãã®ïŒAnimationControllerïŒãç°¡åã«åæã§ããŸãã AnimatedBuilder + AnimatorController.use()
ã§ãåãããšãã§ããã®ã§ãTABã¯ã»ãšãã©ç¡æå³ã«ãªããŸãã
ã¢ãã¡ãŒã·ã§ã³ã®åšãã«åºçŸããèšå€§ãªæ°ã®ãŠã£ãžã§ãããèŠããšãäžè¬çãªãŠãŒã¹ã±ãŒã¹ã®å¿ èŠæ§ãå®éã«ç€ºãããŠããŸãã ã³ã¢ã»ããã¢ãã/ãã£ã¢ããŠã³ããžãã¯ãåå©çšããã®ã¯éåžžã«é¢åã§ãã°ãçºçããããããã15以äžã®ãŠã£ãžã§ããããã¹ãŠéåžžã«ç¹æ®ãªãã®ãåŠçããŠããŸãããããããã®ãŠã£ãžã§ããã®å€§éšåã¯ãã»ãã®äžæ¡ãã§åãã¢ãã¡ãŒã·ã§ã³ã®å®åæãç¹°ãè¿ããŠããŸãå€ãã®å Žåãäžæã®ã³ãŒãè¡ã
ã¯ããç§ãã¡èªèº«ã®ã¹ããŒããã«ããžãã¯ãåå©çšããããã«ãã®ããšãè¡ãããšãã§ããããšã瀺ãã®ã«åœ¹ç«ã¡ãŸãïŒäœ¿çšæ³ã®ãã¹ãŠã®é åã®ããã®ãŠã£ãžã§ãããäœæããŸãã ãããããªããšé¢åã§ã¡ã³ããã³ã¹ã®é çã®çš®ã§ãã lifceycleããã¯ã䜿çšããŠãå°ããªã¹ããŒããã«ãªããžã§ã¯ããç°¡åã«äœæããæ¹æ³ããããšãéåžžã«äŸ¿å©ã§ããã¬ã³ããªã³ã°å°çšã®ãŠã£ãžã§ãããåå©çšå¯èœãªãã«ããŒãäœæããå Žåã¯ãããããç°¡åã«äžã«éããããšãã§ããŸãã
䟡å€ãããã®ã§ãç§ã¯éåžžã®ã¢ãã¡ãŒã·ã§ã³ãŠã£ãžã§ããã§ã¯ãªãã useAnimation
ãããªãã®ãã¢ããªã§å€çšããŠããŸãã ããã¯ãããšãã°AnimatedContainerã®ãããªãŠã£ãžã§ããã§ã¯ååã«ãµããŒããããŠããªãSpringAnimationã䜿çšããŠããããã§ãã ãããã¯ãã¹ãŠã Simulation
åŒæ°ãåãå
¥ããã·ãã¥ã¬ãŒã·ã§ã³ããŒã¹ã®ã¢ãã¡ãŒã·ã§ã³ã§ã¯ãªãã curve
ãšduration
æéããŒã¹ã®ã¢ãã¡ãŒã·ã§ã³ãæ³å®ããŠããŸãã
useAnimation
è¶
ããŠæœè±¡åããŸããããã¹ããªã³ã°ã䜿çšããããã useSpringAnimation
ãšåŒã³ãŸããã ãã®ããã¯ã䜿çšããã©ãããŒãŠã£ãžã§ããã¯AnimatedContainer
䌌ãŠããŸãããããžãã¯ã®å€ããåãã§ããããã @ esDotDevãšèšãAnimatedContainer
ãã ããäžåºŠuseSpringAnimation
ã䜿çšããŠããã¹ãŠã®ã¢ãã¡ãŒã·ã§ã³ãŠã£ãžã§ããã®ç¬èªã®ããŒãžã§ã³ãäœæããããšãã§ããŸãããããããžã§ã¯ãã«å¿
ãããå¿
èŠã§ã¯ãããŸãã
ããšãã°ãvar anim = AnimationController.useïŒcontextãdurationïŒwidget.duration ?? _durationïŒ;ã®å Žåã®æ¹æ³ãèããŠã¿ãŸãã 第äžçŽåžæ°ã§ããããããã®æé»çãŸãã¯æ瀺çãªã¢ãã¡ãŒã·ã§ã³ã¯äºå®äžååšããå¿ èŠã¯ãããŸããã ãããã¯ãã¹ãŠã³ã¢ã®åé¡ã管çããããã«äœæãããŠãããããåé·ã«ãªããŸãããŠã£ãžã§ããã®ã³ã³ããã¹ãå ã§ã¹ããŒããã«ãªãã®ïŒAnimationControllerïŒãç°¡åã«åæã§ããŸãã AnimatedBuilder + AnimatorController.useïŒïŒã§ãåãããšãã§ããã®ã§ãTABã¯ã»ãšãã©ç¡æå³ã«è¿ããªããŸãã
äžèšã®ç§ã®ã³ã¡ã³ããèªããšãããã¯åºæ¬çã«ç§ãæ¥ã®ã¢ãã¡ãŒã·ã§ã³ããã¯ã§è¡ã£ãããšãšãŸã£ããåãããã§ãã ããžãã¯ãã«ãã»ã«åããŠãããåã«AnimatedBuilderã䜿çšããŸããã ããããæé»çã«ããããã«ãAnimatedContainerã§è¡ãããã«å°éå
·ãå€æŽãããšãã¢ãã¡ãŒã·ã§ã³åãããã®ã§ã didUpdateWidget
ïŒ flutter_hooks
ã§ã¯didUpdateHook
ãšåŒã°ããŸãïŒã¡ãœãããã«è¿œå ããŸãããå€ãå€ããæ°ããå€ã«ã¢ãã¡ãŒã·ã§ã³ãå®è¡ããŸãã
https://github.com/TimWhiting/local_widget_state_approaches/tree/master/lib/statefulã®äŸãã人ã ã解決ãããåé¡ã代衚ããŠãããšä»®å®ããã®ã¯æ£ããã§ããïŒ
æ£çŽããããããŸããã
ç§ã¯_ã¯ã_ãšèšããŸãã ããããããã¯æ¬åœã«ãããã®äŸãã©ã®ããã«è§£éãããã«äŸåããŸãããã®ã¹ã¬ããã§ã¯ããäºããç解ããŠããªããšããæŽå²ãããã®ã§ããããäºåºŠãšèµ·ãããªãããšãä¿èšŒããããšã¯ã§ããŸããã
ãã®ãããã³ãŒãäŸã®äœ¿çšãå«ãã§ã代ããã«äžé£ã®ã«ãŒã«ãæœåºããããšãææ¡ããŸããã
äŸã¯äž»èŠ³çãªãã®ã§ãããè€æ°ã®è§£æ±ºçããããŸããããã®äžã«ã¯ããåºç¯ãªåé¡ã解決ã§ããªããã®ããããŸãã
ãŸãããã®å·ã§èª¬æãããã¹ãŠã®ã³ãŒããµã³ãã«ãå«ããå¿ èŠããããšæããŸãã @ rrousselGitãäœæãããªã¹ããäžèšã®ã©ããã«ãããšæããŸãã ããããlocal_stateãªããžããªã«è¿œå ããPRãäœæããããšã¯ã§ããŸããããã¹ãŠãå®å šãªã³ãŒãäŸã§ã¯ãªãããããã¹ãŠãå®éã«ã³ã³ãã€ã«ããã³å®è¡ããããšã¯éããŸããã ããããå°ãªããšãæœåšçãªåé¡ã瀺ããŠããŸãã
ããããlocal_stateãªããžããªã«è¿œå ããPRãäœæã§ããŸã
ããã¯éåžžã«äŸ¿å©ã§ãã
ãã®ã¹ã¬ããã¯åå©çšãåå©çšãã©ã®ããã«èŠããããå®çŸ©ããŠããªãããšãææããããšæããŸãã äŒè©±ã®çŠç¹ã倱ãããªãããã«ããããå®çŸ©ããéã«ã¯çã ããã»ã©å ·äœçã«ãã¹ãã ãšæããŸãã
Flutterã«é¢é£ããåå©çšã_ãªã_ãã®ã瀺ããã ãã§ãã
ããªãã®æ°ã®äœ¿çšäŸããããããã¯ã¯æããã«ãŠã£ãžã§ããç¶æ ã®åå©çšã®å šäœçãªäŸãæäŸããŸãã æ··ä¹±ã¯äžèŠããããããããã«èŠããã®ã§ãã©ãããæ¥ãŠããã®ãããããŸããã
åå©çšã¯ã次ã®ããã«ç°¡åã«å®çŸ©ã§ããŸãã_ãã«ããŒãŠã£ãžã§ããã§ã§ããããšã_
質åã¯ããŠã£ãžã§ããå ã«ååšã§ããã¹ããŒããã«ãªããžã§ã¯ããæ±ããŠããŸãã
ãããŠã次ã®ããã«ãç°¡åã«æºåã§ãããã€ã©ãŒãã¬ãŒãã®ãªãæ¹æ³ã§ãããè¡ããŸãã
AnimationController anim = AnimationController.stateful(duration: widget.duration);
ãããã¹ããŒãã¬ã¹ãŠã£ãžã§ãããšã¹ããŒããã«ãŠã£ãžã§ããã§æ©èœããå Žåã widget.somethingãå€æŽããããšãã«åæ§ç¯ãããç¬èªã®initïŒïŒãšdisposeïŒïŒãå®è¡ã§ããå Žåã¯ãåºæ¬çã«åè
ãããã®ã§ã誰ããåãã§ããããšç¢ºä¿¡ããŠããŸãã
ç§ãèŠåŽããŠããäž»ãªããšã¯ããããå¹ççãªæ¹æ³ã§è¡ãæ¹æ³ã§ãã ããšãã°ãValueListenableBuilderã¯ãããã©ãŒãã³ã¹ã枬å®å¯èœã«åäžãããããã«äœ¿çšã§ããååŒæ°ãåããŸãã ããããã£ã¢ãããŒãã§ãããè¡ãæ¹æ³ãããããŸããã
ããã¯åé¡ã§ã¯ãªããšç¢ºä¿¡ããŠããŸãã ããã¯ã XTransition
ãŠã£ãžã§ãããçŸåšæ©èœããã®ãšåãæ¹æ³ã§è¡ããŸãã è€éãªç¶æ
ããããé«äŸ¡ãªåãå¿
èŠãªå Žåã¯ããã®ããã®å°ããªã©ãããŒãŠã£ãžã§ãããäœæããŸãã ç§ãã¡ãäœããããããªãã®ãšåãããã«ïŒ
FadeTransition(opacity: anim, child: someChild)
'thing'ããŠã£ãžã§ããã«æž¡ããŠåã¬ã³ããªã³ã°ããããšã§ãã¬ã³ããªã³ã°ããããã®ã䜿ã£ãŠåãããã«ç°¡åã«ãããè¡ãããšãã§ããŸãã
MyThingRenderer(value: thing, child: someChild)
@esDotDevã«åæããŸããã åã«è¿°ã¹ãããã«ãããã®ä»£æ¿ã¿ã€ãã«ã¯ããã«ããŒã®ããã®æ§æç³è¡£æ§æãã§ãã
ç§ãèŠåŽããŠããäž»ãªããšã¯ããããå¹ççãªæ¹æ³ã§è¡ãæ¹æ³ã§ãã ããšãã°ãValueListenableBuilderã¯ãããã©ãŒãã³ã¹ã枬å®å¯èœã«åäžãããããã«äœ¿çšã§ããååŒæ°ãåããŸãã ããããã£ã¢ãããŒãã§ãããè¡ãæ¹æ³ãããããŸããã
ããã¯åé¡ã§ã¯ãªããšç¢ºä¿¡ããŠããŸãã ããã¯ã
XTransition
ãŠã£ãžã§ãããçŸåšæ©èœããã®ãšåãæ¹æ³ã§è¡ããŸãã è€éãªç¶æ ããããé«äŸ¡ãªåãå¿ èŠãªå Žåã¯ããã®ããã®å°ããªã©ãããŒãŠã£ãžã§ãããäœæããŸãã ç§ãã¡ãäœããããããªãã®ãšåãããã«ïŒ
ãã®å¿
èŠã¯ãããŸããã
ãã®æ©èœã®å©ç¹ã®1ã€ã¯ãããã©ã¡ãŒã¿ãŒãå€æŽãããªãã£ãå Žåã«ãŠã£ãžã§ããã€ã³ã¹ã¿ã³ã¹ããã£ãã·ã¥ããããšããç¶æ
ããžãã¯ã䜿çšã§ããããšã§ãã
ããã¯ã䜿çšãããšãReactã§ã¯useMemo
ã«ãªããŸãã
<insert whatever>
final myWidget = useMemo(() => MyWidget(pameter: value), [value]);
ãã®ã³ãŒãã䜿çšãããšã myWidget
value
ãå€æŽããããšãã«myWidget
ã_only_ãåæ§ç¯ããŸãã useMemo
ãåŒã³åºããŠã£ãžã§ãããä»ã®çç±ã§åæ§ç¯ããããšããŠãã
ããã¯ãŠã£ãžã§ããã®constã³ã³ã¹ãã©ã¯ã¿ãŒã«äŒŒãŠããŸãããåçãã©ã¡ãŒã¿ãŒãèš±å¯ããŸãã
ãã£ã ã®ãªããžããªã«ãããè¡ãäŸããããŸãã
質åã¯ããŠã£ãžã§ããå ã«ååšã§ããã¹ããŒããã«ãªããžã§ã¯ããæ±ããŠããŸãã
- èªèº«ã®ç¶æ ãã«ãã»ã«åããŸã
- initState / disposeåŒã³åºãã«åŸã£ãŠããèªäœãã»ããã¢ãã/ãã£ã¢ããŠã³ã§ããŸã
- ãŠã£ãžã§ããã§äŸåé¢ä¿ãå€æŽããããšãã«åå¿ã§ããŸã
ãããã®ãã©ã¡ãŒã¿ãŒã«ãã£ãŠã StatefulWidget
ããããããããŸãæ©èœããªãçç±ãç解ããã®ã«èŠåŽããŠãããšæããŸãã ã ãããããç§ã¯ããã§è§£æ±ºçãšããŠæ¬åœã«äœãæ±ããŠããã®ããšãã質åãããŸããã flutter_hooks
ã䜿çšãã人ãšããŠã StatefulWidget
ãããæäœã楜ãããšæããŸãããããã¯åé·æ§ãåé¿ããããã ãã§ãããããã¯ã®èŠ³ç¹ããèããããã§ã¯ãããŸããã ç§ã¯å®éã Widget
ãšæ¯èŒããŠãããã¯ã䜿çšããUIã®æŽæ°ã«ã€ããŠã®æšè«ãé£ãããšæããŠããŸãã
- ãŠã£ãžã§ããã§äŸåé¢ä¿ãå€æŽããããšãã«åå¿ã§ããŸã
ãŠã£ãžã§ããå ã§äœæ/ååŸãããäŸåé¢ä¿ãæå³ããŸããïŒ ãŸãã¯ãããªãŒã®ãŠã£ãžã§ããã®ã¯ããäžã«ããäŸåé¢ä¿ã§ããïŒ
Flutterã«åé·æ§/æ··ä¹±ãåŒãèµ·ããåé¡ãããããšãåŠå®ããŠããããã§ã¯ãããŸããããåå©çšããšã¯äœããšããåãã¡ã³ã¿ã«ã¢ãã«ãå®éã«æã£ãŠãããã¹ãŠã®äººã«é Œãã®ããããã£ãŠããŸãã 説æã«ãšãŠãæè¬ããŠããŸãã ãããŠã人ã ãç°ãªãã¢ãã«ãæã£ãŠãããšãã圌ãã¯ç°ãªããœãªã¥ãŒã·ã§ã³ãäœæããŸãã
SWã䜿çšããŠãããè¡ãããšã¯ãç¹å®ã®ãŠãŒã¹ã±ãŒã¹ã§ã¯åé¡ãããŸããããå€ãã®SWã§ãŠãŒã¹ã±ãŒã¹ã®åå©çšå¯èœãªããžãã¯ãæœè±¡åããã®ã«ã¯é©ããŠããŸããã äŸãšããŠãã¢ãã¡ãŒã·ã§ã³ã®ã»ããã¢ãã/å解ãåãäžããŸãã ããã¯SWèªäœã§ã¯ãªããSWå šäœã§äœ¿çšããããã®ã§ãã ã«ãã»ã«åãããç¶æ ãå ±æããããã®ãã¡ãŒã¹ãã¯ã©ã¹ã®ãµããŒãããªããã°ããã«ããŒïŒTweenAnimationBuilderïŒãäœæããããç¹å®ã®ãŠã£ãžã§ããïŒAnimatedContainerãªã©ïŒã倧éã«äœæããå¿ èŠããããŸãããã®ããžãã¯ããã³ãã«ããŠåå©çšã§ããã°ãæ¬åœã«ã¯ããã«ãšã¬ã¬ã³ãã«ãªããŸããæšã®äžã§å¥œããªããã«ã
ãŠã£ãžã§ããã®äŸåé¢ä¿ã«é¢ããŠèšãã°ã widget.foo
ãå€æŽãããå Žåãã¹ããŒããã«ãªãã®ã¯ãå¿
èŠãªæŽæ°ãè¡ãæ©äŒãåŸããšããããšã§ãã stateful
AnimationControllerã®å Žåãæéãå€æŽããããã©ããã確èªããå€æŽãããå Žåã¯ãå
éšAnimatorControllerã€ã³ã¹ã¿ã³ã¹ãæŽæ°ããŸãã ããã«ãããã¢ãã¡ãŒã·ã§ã³ã®ãã¹ãŠã®å®è£
è
ãããããã£ã®å€æŽãåŠçããå¿
èŠããªããªããŸãã
<insert whatever> final myWidget = useMemo(() => MyWidget(pameter: value), [value]);
ãã®ã³ãŒãã䜿çšãããšã
myWidget
value
ãå€æŽããããšãã«myWidget
ã_only_ãåæ§ç¯ããŸããuseMemo
ãåŒã³åºããŠã£ãžã§ãããä»ã®çç±ã§åæ§ç¯ããããšããŠãã
ãªãã»ã©ãMemoizedã¯ãŠã£ãžã§ããèªäœãè¿ãã[value]ãåæ§ç¯ããªã¬ãŒãšããŠæž¡ããŸãã
AnimatedOpacityã®éµã¯ã芪ã§ãåã§ãåæ§ç¯ããããšã§ã¯ãããŸããã å®éãAnimatedOpacityã䜿çšããŠã¢ãã¡ãŒã·ã§ã³ãããªã¬ãŒãããšãã¢ãã¡ãŒã·ã§ã³ãããªã¬ãŒããæåã®ãã¬ãŒã ã®åŸã«æåéãäœãåæ§ç¯ãããŸããã ãã«ããã§ãŒãºãå®å šã«ã¹ããããããã¹ãŠãã¬ã³ããŒãªããžã§ã¯ãã§å®è¡ããŸãïŒã¬ã³ããŒããªãŒã§ã¯ãåãã€ã³ãã®ã¿ã§ããããªã¬ãŒã¢ãŠãã§ã¯ãããŸãããå®éãã¬ã€ã€ãŒã䜿çšããããããã€ã³ããéåžžã«æå°éã«æããããŸãïŒã ããã¯ãããã©ãŒãã³ã¹ãšããããªãŒäœ¿çšéã«å€§ããªéãããããããŸãã ããã§æãã€ãããœãªã¥ãŒã·ã§ã³ãäœã§ããããããã³ã¢ãã¬ãŒã ã¯ãŒã¯ã«çµã¿èŸŒãå Žåã¯ããã®ãããªããã©ãŒãã³ã¹ãç¶æã§ããå¿ èŠããããŸãã
æ®å¿µãªããããã®å·ã®äŸãå°å ã®å·ã®ã¬ãã«ãŸãšããæéããããŸããã§ããã è¿ããã¡ã«æãå±ããªããããããªãã®ã§ãä»ã®èª°ãããããæã«å ¥ãããã®ãªããç§ã¯ããã§å€§äžå€«ã§ãããã
build / renderã¡ãœããå
ã§ããã¯ãå®çŸ©ããããã©ãŒãã³ã¹ïŒãã®å·ã®ååã§èª°ããèšåãããšæããŸãïŒã«é¢ããŠã¯ãReactã®ããã¥ã¡ã³ããèªãã§ããŠããã®FAQã圹ç«ã€ãããããŸããã åºæ¬çã«ããã¹ãŠã®ã¬ã³ããªã³ã°ã§é¢æ°ãäœæããããã«ããã¯ãé
ããã©ãããå°ããŸãããããã€ãã®çç±ã§ããããããšçããŸãããã®1ã€ã¯ã useMemo
ãuseCallback
ãªã©ã®ããã¯ã䜿çšããŠé¢æ°ãã¡ã¢åã§ããããšã§ãã
https://reactjs.org/docs/hooks-faq.html#are -hooks-slow-because-of-creating-functions-in-render
åºæ¬çã«ããã¹ãŠã®ã¬ã³ããªã³ã°ã§é¢æ°ãäœæããããã«ããã¯ãé ããã©ãããå°ããŸãããããã€ãã®çç±ã§ããããããšçããŸãããã®1ã€ã¯ã
useMemo
ãuseCallback
ãªã©ã®ããã¯ã䜿çšããŠé¢æ°ãã¡ã¢åã§ããããšã§ãã
å¿é ã¯ã¯ããŒãžã£ãŒãäœæããã³ã¹ãã«ã€ããŠã§ã¯ãããŸããããããã¯ç¢ºãã«æ¯èŒçå®ãã§ãã ä»æ¥ã®æé©ãªã±ãŒã¹ã§Flutterã瀺ãããã©ãŒãã³ã¹ã®éµãšãªãã®ã¯ãã³ãŒãããŸã£ããå®è¡ããªãå Žåãšå®è¡ããªãå Žåã®éãã§ãã ç¹å®ã®ã³ãŒããã¹ã®å®è¡ãæåéãåé¿ããã¢ã«ãŽãªãºã ã®äœæã«å€å€§ãªåŽåãè²»ãããŸããïŒããšãã°ãAnimatedOpacityã®ããã«ãã«ããã§ãŒãºãå®å šã«ã¹ããããããæ¹æ³ããããªãŒããã©ã£ãŠæŽæ°ãå®è¡ããã®ãåé¿ãã代ããã«åœ±é¿ãåããããŒãã®ã¿ãã¿ãŒã²ããã«ããæ¹æ³ïŒã
åæããŸãã ç§ã¯Flutterã®å éšãããã¯ã®å éšã«ããŸã粟éããŠããŸããããããã¯ã¯ãã€å®è¡ããããå®è¡ããªãããå€æããå¿ èŠããããããã©ãŒãã³ã¹ãäœäžããŠã¯ãªããŸããã
ä»æ¥ã®æé©ãªã±ãŒã¹ã§Flutterã瀺ãããã©ãŒãã³ã¹ã®éµãšãªãã®ã¯ãã³ãŒãããŸã£ããå®è¡ããªãå Žåãšå®è¡ããªãå Žåã®éãã§ãã
åã«æ°åè¿°ã¹ãããã«ãããã¯ã¯ãããæ¹åããŸãã
ãã£ã ã®ã¬ãã®ã¢ãã¡ãŒã·ã§ã³ã®äŸã¯ãã®èšŒæ ã§ãã useMemo
ãããã§ãããã¯ããªã¢ã³ãã¯StatefulWidgetããªã¢ã³ããããåæ§ç¯ã®é »åºŠãäœããªããŸã
ãã®ã¹ã¬ããã®ã©ããã§ãã®åé¡ã®è§£æ±ºçã«ã€ããŠè°è«ãããŠããã®ã§ãç§ããããææ¡ãšããŠã©ãã«ä»ãããŠããŸãã
reactã§è¡ãããããã«ãããã¯ããã©ãã¿ãŒã«çµã¿èŸŒãŸããããšãæ¬åœã«æãã§ããŸãã ç§ã¯æåã«reactã䜿çšãããšããšåãããã«ãç¶æ ããã©ãã¿ãŒã§èŠãŠããŸãã ããã¯ã䜿ã£ãŠããã®ã§ãå人çã«ã¯äºåºŠãšæ»ããŸããã
ããã¯ã¯ããã«èªã¿ãããIMOã§ãã çŸåšãusestateã«ããããããã ãã®ããã¯ã«å¯ŸããŠãã¹ããŒããã«ãŠã£ãžã§ããã䜿çšããŠ2ã€ã®ã¯ã©ã¹ã宣èšããå¿ èŠããããŸãã
ãŸãããã©ãã¿ãŒã³ãŒããèŠããšãã«éçºè ããã°ãã°æã£ãŠããªãåå¿ããã©ãã¿ãŒã«ããçšåºŠæ £ããããã§ãããã æããã«ããã©ãã¿ãŒãšãªã¢ã¯ã·ã§ã³ãæ¯èŒããããšã¯å±éºãªéã§ãããããã¯ã䜿çšããéçºè ã®çµéšã¯ãããã¯ã䜿çšããªãçµéšãããåªããŠãããšæããŸãã
ç§ã¯ãã©ãã¿ãŒãå«ãã§ã¯ãããŸãããå®éã«ã¯ç§ã®ãæ°ã«å ¥ãã®ãã¬ãŒã ã¯ãŒã¯ã§ãããããã¯èªã¿ããããšéçºçµéšãåäžãããããã®æ¬åœã«è¯ãæ©äŒã ãšæããŸãã
åœåèŠåãæ¹åãããããã©ãã¿ãŒã®ããã«ããæ©äŒã¯ééããªããããšæããŸãã
UseMemoizedãUseEffectã®ãããªãã®ã¯ããªãç°è³ªã«èãããŸããããã«ãfxnã§initïŒïŒã³ãŒããå®è¡ããå¿ èŠããªãæ¹æ³ãå¿ èŠãªããã§ãã
çŸåšãããã¯ã§åæåããã®ã¯æ¬¡ã®ããã«ãªããŸãïŒç§ã¯æããŸããïŒïŒïŒ
Widget build(){
useEffect(
(){
// Do init stuff
return (){ //Do dispose stuff };
}, [ ] ) //<-- pass an empty list of rebuild triggers, so this can only fire once. Passing null here would let it fire every time.
);
}
ãã®ã³ãŒãã®ç°¡æœãã«æè¬ããŸãããèªã¿ããããšãèªå·±ææžåã³ãŒããã®èŠ³ç¹ããã¯ã確ãã«çæ³çãšã¯èšããŸããã ããã§ã¯å€ãã®æé»ã®éæ³ãèµ·ãã£ãŠããŸãã çæ³çã«ã¯ãinit / disposeããã¯ã«ã€ããŠæ瀺çã§ãããã¹ããŒãã¬ã¹ãŠã£ãžã§ããã§äœ¿çšããããšãã«ããèªäœããã«ãã«åŒ·å¶ããªããã®ããããŸãã
useMemoizedãuseEffectã®ãããªãã®ã¯ãããæ確ã«hook ComputedValue()
ãšhook SideEffect()
ãšããååãä»ããæ¹ãããã§ãããã
Widget build(BuildContext context){
List<int> volumes = hook ComputedValue(
execute: ()=>_getVolumeFromAudioSamples(widget.bytes),
dependencies: [ widget.bytes ]);
hook SideEffect(
execute: ()=>_recordSongChangedAnalytics()
dependencies: [ widget.songUrl ]);
)
return SongVisualizer(volumes: volumes);
}
ç§ã¯ããã奜ãã§ããã hook
ããŒã¯ãŒãã®äœ¿çšã«ã€ããŠã©ãæããã¯ããããŸãããããããå€åœã®æŠå¿µã®åé¡ã解決ãããšã¯æããŸããã æ°ããããŒã¯ãŒããå°å
¥ããããšã¯ãç§ã®é ã®äžã§æåã®ã¢ãããŒããšã¯æããŸããã withSideEffect
ãŸãã¯withComputedValue
ïŒ ç§ã¯èšèªãã¶ã€ããŒã§ã¯ãªãã®ã§ãç§ã®èšèã¯ç¡æå³ã§ãã
Flutterã®ããã¯ã®ãããªæ©èœã¯ãReactéçºè ã®åŠç¿æ²ç·ãã¹ã ãŒãºã«ããã®ã«å€§ãã«åœ¹ç«ã€ãšæããŸããããã¯ãäŒæ¥ãReactNativeãšFlutterã®ã©ã¡ããéžæãããã決å®ããéã®ã¿ãŒã²ãããªãŒãã£ãšã³ã¹ã§ãã
@lemusthelroyãšåãããã«ãFlutterã¯ç§ã®ãæ°ã«å ¥ãã®ãã¬ãŒã ã¯ãŒã¯ã§ããããã®æ¹åæ§ãèŠãã®ã¯ãšãŠã楜ãã¿ã§ãã ããããé¢æ°åããã°ã©ãã³ã°ã®æŠå¿µã¯ããŸã æ¯èŒçæªèžã®æ¹åã«ãã¬ãŒã ã¯ãŒã¯ãæé·ãããäžã§å€§ããªå©ãã«ãªããšæããŸãã Reactããè·é¢ã眮ãããšãç®çãšããŠããã®ã¢ã€ãã¢ãåŽäžããŠãã人ããããšæããŸããããã¯æ®å¿µã§ãããç解ã§ããããšã§ãã
ãã®ã³ã€ã³ã«ã¯2ã€ã®åŽé¢ããããšæããŸãã æ°ããããŒã¯ãŒãã¯äž»èŠãªã€ãã³ãã§ãããããç¥èã®äŒæã¯éåžžã«è¿ éã«ãªããŸãããå察åŽã¯ç¢ºãã«ãããã_everyone_ã«ãšã£ãŠæ°ãããã®ã«ãªã£ãããšã§ãã ããããªããŠãå¯èœãªããããã¯ãŒã«ã§ãïŒ ç¢ºãã§ã¯ãããŸãã...å°ãªããšããšã¬ã¬ã³ãã§ã¯ãããŸããã
æèŠïŒãã®åé¡ã®äºå®äžã®è§£æ±ºçãšããŠããã¯ã«ååãä»ãããšããã³ãã¥ããã£ã®åŸåã¯ãæ©èœãžã®åèŠã«æ ¹ãããŠããŸãã ç¹ã«éçã«åä»ããããèšèªã§ã¯ãé¢æ°ã¯ãªããžã§ã¯ããããäœæãç°¡åã§ãã å€ãã®éçºè
ã«ãšã£ãŠã®ãŠã£ãžã§ããã®ã¡ã³ã¿ã«ã¢ãã«ã¯ãäºå®äžbuild
ã¡ãœããã«ãããªããšæããŸãã
åºæ¬çãªèŠ³ç¹ããåé¡ãçµã¿ç«ãŠããšãã©ã€ãã©ãªã®ä»ã®éšåã§ããŸãæ©èœãããœãªã¥ãŒã·ã§ã³ãèšèšããå¯èœæ§ãé«ããªããšæããŸãã
åºæ¬çã«hook
ããŒã¯ãŒãã«ã€ããŠã¯; ããçš®ã®ãã³ãã¬ãŒãïŒãã¯ãïŒããé¢æ°ã宣èšããã³å®çŸ©ããããšã®äž¡æ¹ãšèŠãªãããšãã§ãã hook
ãã¬ãã£ãã¯ã¹ã¯ãå®éã«ã¯ããã«ããããé¢æ°ãå
éšç¶æ
ïŒcã¹ã¿ã€ã«ã®éçïŒãæã£ãŠããããšãåŒã³åºããŠããã ãã§ãã ïŒ
SwiftFunctionBuildersã«ã¯ããçš®ã®å è¡æè¡ããªãã®ã ãããã
ç§ãã¡ã倢ãèŠãŠããéãç§ã¯å¿ èŠãªã³ãŒããäœã§ãããã«ã€ããŠã®ç§ã®æšæž¬ãæ確ã«ããŸãïŒ
Hook SideEffect(void Function() execute, List<Object> dependencies) {
// Whatever happens each build.
}
Widget build(BuildContext context){
List<int> volumes = hook ComputedValue(
execute: ()=>_getVolumeFromAudioSamples(widget.bytes),
dependencies: [ widget.bytes ]);
SideEffect(
execute: ()=>_recordSongChangedAnalytics()
dependencies: [ widget.songUrl ]);
)
return SongVisualizer(volumes: volumes);
}
ããã§ã Hook
ã¯åã·ã¹ãã ã¬ãã«ã®ããã¯ã§ãããããã¯ã«ç²Ÿéããéçºè
ãããã¯ã®æ³åãšããŠç¥ã£ãŠããæ¹æ³ã«åŸã£ãŠãçµæã®ããã¯ãåŒã³åºãããããšãéçã«åæããã®ã«åœ¹ç«ã¡ãŸãã ãã®ãããªãã®ãšããŠãããã¯ã¿ã€ãã¯é¢æ°ã«ãã䌌ãŠããããéçãªå
éšå¯å€ç¶æ
ãæã£ãŠãããã®ãšããŠææžåããããšãã§ããŸãã
ãããæžããŠãããšããç§ã¯å°ãããããããŸãããªããªããããã¯èšèªã®èŠ³ç¹ããã¯ãšãŠãå¥åŠã ããã§ãã ç¹°ãè¿ãã«ãªããŸãããDartã¯ãŠãŒã¶ãŒã€ã³ã¿ãŒãã§ã€ã¹ãäœæããããã«çãŸããèšèªã§ãã ãã®çš®ã®å¥åŠãªããšãã©ããã«ååšããå¿ èŠãããå Žåãããããããããã®å Žæã§ãã ç¹ã«ãã®å¥åŠãªããšã§ã¯ãããŸããã
æèŠïŒãã®åé¡ã®äºå®äžã®è§£æ±ºçãšããŠããã¯ã«ååãä»ãããšããã³ãã¥ããã£ã®åŸåã¯ãæ©èœãžã®åèŠã«æ ¹ãããŠããŸãã ç¹ã«éçã«åä»ããããèšèªã§ã¯ãé¢æ°ã¯ãªããžã§ã¯ããããäœæãç°¡åã§ãã å€ãã®éçºè ã«ãšã£ãŠã®ãŠã£ãžã§ããã®ã¡ã³ã¿ã«ã¢ãã«ã¯ãäºå®äžãåãªããã«ãã¡ãœããã ãšæããŸãã
ããªããããã§äœãèšãããã®ãããããŸããã get_it_mixinã§ã䜿çšããããã¯ã¢ãããŒãã«ããããã«ããŒã䜿çšããããããŠã£ãžã§ããããªãŒãèªã¿ããããªããŸãã
Reactããã¯ã«é¢ããèå³æ·±ãèšäº
@ nt4f04uNdããã©ãŒãã³ã¹ãã³ã¢æ©èœã§ããå¿ èŠãããçç±ãæ©èœãšã¯ã©ã¹ã¹ã¿ã€ã«ã®ãŠã£ãžã§ãããããã¯ä»¥å€ã®ãã®ãæ©èœããªãããã«èŠããçç±ãªã©ããã¹ãŠã®ãã€ã³ãã¯ä»¥åã«å¯ŸåŠãããŸããã äŒè©±å šäœãèªãã§ãããŸããŸãªãã€ã³ããç解ããããšããå§ãããŸãã
äŒè©±å šäœãèªãã§ãããŸããŸãªãã€ã³ããç解ããããšããå§ãããŸãã
圌ããã¹ã¬ããå šäœãèªãã§ããªãããšãèãããšãããã¯èšããŸã§ããããŸããããã¹ã¬ããã®æ®ãã®éšåãèªãããšããã以äžæ確ã«ãªããã©ããã¯ããããŸããã ãŠã£ãžã§ããããã®ãŸãŸã«ããŠããããšãåªå ãã人ã ãšãä»ã®ããšãå®å šã«è¡ããããŠã£ãžã§ãããããã¢ãžã¥ãŒã«åããããšãæãã§ããå¥ã®ã°ã«ãŒãããããŸãã
ããã¯æ¬åœãããããŸãããããã®åé¡ã¯ãçŸåšã®ãŠã£ãžã§ããã§ã¯è§£æ±ºã§ããªãåé¡ãããããšã瀺ããŠããã®ã§ãåé¡ã解決ãããã®ã§ããã°ãäœãæ°ãããã®ãäœããããªãã®ã§ãã ããã¯ã Future
ãåŸã§async/await
æ§æãå°å
¥ããã®ãšåãæŠå¿µã§ããåŸè
ã䜿çšãããšãæ°ããæ§æãªãã§ã¯äžå¯èœã ã£ãããšãå¯èœã«ãªããŸãã
ãããã人ã
ã¯ããããã¬ãŒã ã¯ãŒã¯ã®äžéšã«ããããšãææ¡ããŠããŸãã Reactã¯å©çšå¯èœãªãã¬ãŒã ã¯ãŒã¯ãå¯äžã§ã¯ãªãããïŒBabelå€æãä»ããŠå¯èœïŒãJavascriptã«æ°ããæ§æãè¿œå ã§ããŸããããDartã¯FlutterïŒå°ãªããšããå
ã®ããŒãžã§ã³ã§ã¯ãªããDart 2ïŒã§åäœããããã«ç¹å¥ã«èšèšãããŠããŸããããã¯ãåºç€ãšãªãèšèªãšé£æºãããæ©èœã®å€ãã ããšãã°ãReactã«ã¯JSXçšã®Babelãå¿
èŠã§ããã useEffect
ãšã©ãŒã«ã¯ãªã³ã¿ãŒã䜿çšããå¿
èŠããããŸãããã³ã³ãã€ã«æãšã©ãŒã«ããããšãã§ããŸãã ããã±ãŒãžããããšãReactããã¯ããµãŒãããŒãã£ã®ããã±ãŒãžã§ãã£ãå Žåã«åŸãããã§ãããïŒåŸãããªãã£ãïŒçœåŒåãæ³åã§ããããã«ãæ¡çšãéåžžã«é£ãããªããŸãã
çŸåšã®ã¹ããŒãã¬ã¹ãŠã£ãžã§ãããšã¹ããŒããã«ãŠã£ãžã§ããã®ã»ãã«ã3çªç®ã®ã¿ã€ãã®ãŠã£ãžã§ããïŒHookWidgetïŒãããã°åé¡ãããŸããã ã©ã¡ãã䜿çšããããã³ãã¥ããã£ã«æ±ºå®ãããŸãã ã¬ãããã®ããã±ãŒãžã¯ãã§ã«ãããŸãããå¿ ç¶çã«å¶éããããŸãã ç§ã¯ãããè©ŠããŸããããããŠããã¯ãã€ã©ãŒãã¬ãŒããããªãæžãããŸããããããç§ã¯å¶éã®ããã«ãããäžå¹žã«ãèœãšããªããã°ãªããŸããã§ããã initã¡ãœããã䜿çšããããã ãã«ã¹ããŒããã«ãŠã£ãžã§ãããäœæããå¿ èŠããããŸãã èšèªããµããŒãããã³ã¢ãã¬ãŒã ã¯ãŒã¯ã®äžéšã§ããå Žåãããã«å€§ããªã¡ãªããããããŸãã ããã«ãHookWidgetã䜿çšãããšãã³ãã¥ããã£ã¯ããæé©ã§ããã©ãŒãã³ã¹ã®é«ãã¢ããªãäœæã§ããŸãã
initã¡ãœããã䜿çšããããã ãã«ã¹ããŒããã«ãŠã£ãžã§ãããäœæããå¿ èŠããããŸãã
å®éã«ãããè¡ãå¿ èŠã¯ãããŸãããuseEffectïŒïŒã¯ãã«ãå ã§initCallãå®è¡ã§ããŸãã ããã¥ã¡ã³ãã¯ããã説æããããã«äœã®åªåãããŠããŸããããããŠåºæ¬çã«ããªããããã¯ãã©ã®ããã«åããããã§ã«ç¥ã£ãŠããReactéçºè ã§ãããšä»®å®ããŸãã
ç§ã¯ãã®ããã«äœ¿çšããŠããŸããããããã±ãŒãžã®å¶éã«é¢ããŠä»ã®ããã€ãã®åé¡ããããããããäœã§ãã£ãããæ£ç¢ºã«èŠããŠããŸããã
æãåèã«ãªãã³ã¡ã³ã
Reactã®èŠ³ç¹ããããã€ãã®èããè¿œå ããŸãã
é¢é£æ§ããªãå Žåã¯ã容赊ãã ããããã ããããã¯ã«ã€ããŠã®èãæ¹ãç°¡åã«èª¬æããããšæããŸãã
ããã¯ã¯ééããªãç©ããé ããŠãããã ãŸãã¯ããããã©ã®ããã«èŠããã«å¿ããŠãããããã«ãã»ã«åããŸãã ç¹ã«ããããã¯å±æçãªç¶æ ãšå¹æãã«ãã»ã«åããŸãïŒç§ãã¡ã®ãå¹æãã¯ã䜿ãæšãŠããšåããã®ã ãšæããŸãïŒã ãæé»æ§ããšã¯ãåŒã³åºãããã³ã³ããŒãã³ãã«ã©ã€ãã¿ã€ã ãèªåçã«ä»å ããããšã§ãã
ãã®æé»æ§ã¯ãã¢ãã«ã«åºæã®ãã®ã§ã¯ãããŸããã ã³ã³ããŒãã³ãèªäœããã«ã¹ã¿ã ããã¯å šäœãåããªããã£ãããã¯ã«è³ããŸã§ããã¹ãŠã®åŒã³åºãã«åŒæ°ãæ瀺çã«ã¹ã¬ããåãããŠããããšãæ³åã§ããŸãã ãããå®éã«ã¯ããã€ãºãå€ããå®éã«ã¯åœ¹ã«ç«ããªãããšãããããŸããã ãã®ãããçŸåšå®è¡äžã®ã³ã³ããŒãã³ããæé»çãªã°ããŒãã«ç¶æ ã«ããŸããã ããã¯ãã³ãŒãã§
errorHandlerFrame
ãæž¡ã代ããã«ãVMã®throw
ãæãè¿ãcatch
ãããã¯ãäžåãã«æ€çŽ¢ããæ¹æ³ã«äŒŒãŠããŸããããŠãããã¯ãããã®äžã«æé»ã®é ãããç¶æ ãæã€é¢æ°ã§ããããã¯æªãããã«èŠããŸããïŒ ããããReactã§ã¯ãäžè¬çãªã³ã³ããŒãã³ããããã§ãã ãããã³ã³ããŒãã³ãã®èŠç¹ã§ãã ãããã¯ãæå¹æéãé¢é£ä»ããããŠããé¢æ°ã§ãïŒUIããªãŒå ã®äœçœ®ã«å¯Ÿå¿ããŸãïŒã ã³ã³ããŒãã³ãèªäœãç¶æ ã«é¢ããŠãããã¬ã³ã§ã¯ãªãçç±ã¯ãã©ã³ãã ãªã³ãŒãããã³ã³ããŒãã³ããåŒã³åºãã ãã§ã¯ãªãããã§ãã ä»ã®ã³ã³ããŒãã³ãããããããåŒã³åºããŸãã ãããã£ãŠãUIã³ãŒãã®ã³ã³ããã¹ãã«ãšã©ãŸãããããããã®åç¶æéã¯çã«ããªã£ãŠããŸãã
ãã ãããã¹ãŠã®åé¡ãã³ã³ããŒãã³ãã®åœ¢ãããŠããããã§ã¯ãããŸããã ã³ã³ããŒãã³ãã¯ãç¶æ ãšå¹æãããã³ããªãŒã®äœçœ®ã«é¢é£ä»ããããåç¶æéãšãã2ã€ã®æ©èœãçµã¿åããããã®ã§ãã ããããæåã®èœåã¯ããèªäœã§åœ¹ç«ã€ããšãããããŸããã é¢æ°ãã³ãŒããã«ãã»ã«åã§ããã®ã§äžè¬çã«åœ¹ç«ã€ã®ãšåãããã«ãããªãŒã«æ°ããããŒããäœæããªããŠããç¶æ ãšå¹æã®ãã³ãã«ãã«ãã»ã«åïŒããã³åå©çšïŒã§ããããªããã£ãããããŸããã§ããã ãããããã¯ã§ãã ã³ã³ããŒãã³ã=ããã¯+è¿ãããUIã
å ã»ã©ç³ãäžããããã«ãã³ã³ããã¹ãç¶æ ãé ãä»»æã®é¢æ°ã¯æãã§ãã ãããããªã³ã¿ãŒãä»ããŠèŠåãæœè¡ããçç±ã§ãã ããã¯ã«ã¯ãè²ãããããŸãâããã¯ã䜿çšããå Žåãé¢æ°ã¯ããã¯ã§ããããŸãã ãŸãããªã³ã¿ãŒã¯ãã³ã³ããŒãã³ããŸãã¯ä»ã®ããã¯ã®ã¿ãããã¯ã䜿çšã§ããããã«åŒ·å¶ããŸãã ããã«ãããä»»æã®é¢æ°ãã³ã³ããã¹ãUIã®ç¶æ ãé ããšããåé¡ã解æ¶ãããŸããããã¯ãããããã³ã³ããŒãã³ãèªäœãããæé»çã§ã¯ãªããªã£ãããã§ãã
æŠå¿µçã«ã¯ãããã¯åŒã³åºããåçŽãªé¢æ°åŒã³åºããšã¯èŠãªããŸããã
useState()
use State()
ããã«ãæ§æãããã°ã 代æ°å¹æãåããããã¯ã®ãããªãã®ãã¢ãã«åã§ããŸãã ãããã£ãŠããã®æå³ã§ã¯ããããã¯éåžžã®é¢æ°ã«ãªããŸãããç¶æ ãã䜿çšããããšããäºå®ã¯ãåã·ã°ããã£ã®äžéšã«ãªããŸãã 次ã«ãReactèªäœããã®ãšãã§ã¯ãã®ããã³ãã©ãŒããšèããããšãã§ããŸãã ãšã«ãããããã¯éåžžã«çè«çã§ãããããã°ã©ãã³ã°ã¢ãã«ã®èŠ³ç¹ããå è¡æè¡ãææããããšæããŸãããå®éã«ã¯ãããã«ã¯ããã€ãã®ããšããããŸãã ãŸããããã¯ã¯Reactã®ãè¿œå ã®ãAPIã§ã¯ãªãããšã«æ³šæããŠãã ããã ãããã¯ãçŸæç¹ã§ã³ã³ããŒãã³ããäœæãããã
ããããå¯èœã«ãããã®ã«é¢ããŠã¯ãéèŠãªæ©èœã¯ãç¶æ +å¹æçãªããžãã¯ãã«ãã»ã«åããéåžžã®é¢æ°åæã®å Žåãšåãããã«ããããã§ãŒã³åããæ©èœã ãšæããŸãã ããªããã£ãã¯æ§æããããã«èšèšãããŠããããã
useState()
ãããªããã¯åºåãååŸãããããã«ã¹ã¿ãuseGesture(state)
ãžã®å ¥åãšããŠæž¡ãããããããã€ãã®ã«ã¹ã¿ãuseSpring(gesture)
ãžã®å ¥åãšããŠæž¡ãããšãã§ããŸããåé³¥ç¶ã®å€ãäžããå°ããªãã¢ãšãããã¯ãšã¯äœããç°¡åã«èŠçŽããèšäºã§ããããã¯å®åæãæžããããšã§ã¯ãªããã¹ããŒããã«ã«ãã»ã«åããžãã¯ã®ãã€ãã©ã€ã³ãåçã«æ§æããæ©èœ
ããã圹ã«ç«ã£ããã©ããã¯ããããŸããããããã°ã©ãã³ã°ã¢ãã«ã«äœããã®èŠç¹ãäžããããšãé¡ã£ãŠããŸãã
ä»ã®è³ªåã«ãçãããŸãã