Slide 1

Slide 1 text

No content

Slide 2

Slide 2 text

߱໼େ஍ גࣜձࣾαΠόʔΤʔδΣϯτ ϝσΟΞ౷ׅຊ෦ %FWFMPQFS1SPEVDUJWJUZࣨ XBTBCFFG@KQ XBTBCFFG (PPHMF%FWFMPQFST&YQFSU

Slide 3

Slide 3 text

"HFOEB wαΠόʔΤʔδΣϯτͷ'MVUUFS࠾༻ࣄྫ w'MVUUFS)PPLTΛ࢖ͬͨΞϓϦ։ൃ w 'MVUUFS)PPLTͱ͸ʁ w 4UBUFGVM8JEHFUͷϥΠϑαΠΫϧΛར༻ͨ͠৔߹ w 'MVUUFS)PPLTΛجຊΛཧղ͢Δ w 'MVUUFS)PPLTͷޮՌతͳར༻๏ wࠓޙͷల๬

Slide 4

Slide 4 text

αΠόʔΤʔδΣϯτͷ'MVUUFS࠾༻ࣄྫ

Slide 5

Slide 5 text

'MVUUFSͷ࠾༻ࣄྫ ग़యɿIUUQTXXXDZCFSBHFOUDPKQUFDIJOGPJOGPEFUBJMJE

Slide 6

Slide 6 text

'MVUUFS)PPLTΛ࢖ͬͨΞϓϦ։ൃ

Slide 7

Slide 7 text

'MVUUFS)PPLTͱ͸ʁ

Slide 8

Slide 8 text

'MVUUFS)PPLTͱ͸ʁ ग़యɿIUUQTHJUIVCDPNSSPVTTFM(JU fl VUUFS@IPPLT ग़యɿIUUQTSFBDUKTPSHEPDTIPPLTJOUSPIUNM w 3FBDU)PPLTͷ'MVUUFS൛Ͱจ๏΋࢖͍ํ΋΄΅ಉ͡΋ͷ

Slide 9

Slide 9 text

4UBUFGVM8JEHFUͷ ϥΠϑαΠΫϧΛ ར༻ͨ͠৔߹

Slide 10

Slide 10 text

class CountPage extends StatefulWidget { @override State createState() => _CountState(); } class _CountState extends State { int count = 0; @override void initState() { / ** ॳظԽ **/ } @override void dispose() { /** ഁغ **/ } void setCount(int value) => setState(() = > count = value); @override Widget build(BuildContext context) { return TextButton( child: Text("Count is $count"), onPressed: () => setCount(count + 1), ); } } w γεςϜͷঢ়ଶͳͲʹΑͬͯಈతʹ มԽΛ͢Δখ͞ͳϥΠϑαΠΫϧΛ ΋ͬͨ΢ΟδΣοτ w *NBHFɺ5FYU'PSN'JFME΍)FSPͳ Ͳ͕4UBUFGVM8JEHFUͷαϒΫϥε 4UBUFGVM8JEHFUͷઆ໌

Slide 11

Slide 11 text

class CountPage extends StatefulWidget { @override State createState() => _CountState(); } class _CountState extends State { int count = 0; @override void initState() { / ** ॳظԽ **/ } @override void dispose() { /** ഁغ **/ } void setCount(int value) => setState(() = > count = value); @override Widget build(BuildContext context) { return TextButton( child: Text("Count is $count"), onPressed: () => setCount(count + 1), ); } } 4UBUFGVM8JEHFUΛ࢖͏ʹ͸جຊతʹೋͭͷ ΫϥεΛ࡞Δඞཁ͕͋Δ w 4UBUFGVM8JEHFUΛܧঝͨ͠$PVOU1BHF w 4UBUF5Λܧঝͨ͠@$PVOU4UBUF 4UBUFGVM8JEHFUͷઆ໌

Slide 12

Slide 12 text

class CountPage extends StatefulWidget { @override State createState() => _CountState(); } class _CountState extends State { int count = 0; @override void initState() { / ** ॳظԽ **/ } @override void dispose() { /** ഁغ **/ } void setCount(int value) => setState(() = > count = value); @override Widget build(BuildContext context) { return TextButton( child: Text("Count is $count"), onPressed: () => setCount(count + 1), ); } } 4UBUFGVM8JEHFUͷઆ໌ 4UBUFGVM8JEHFUΛ࢖͏ʹ͸جຊతʹೋͭͷ ΫϥεΛ࡞Δඞཁ͕͋Δ w 4UBUFGVM8JEHFUΛܧঝͨ͠$PVOU1BHF w 4UBUF5Λܧঝͨ͠@$PVOU4UBUF

Slide 13

Slide 13 text

class CountPage extends StatefulWidget { @override State createState() => _CountState(); } class _CountState extends State { int count = 0; @override void initState() { / ** ॳظԽ **/ } @override void dispose() { /** ഁغ **/ } void setCount(int value) => setState(() = > count = value); @override Widget build(BuildContext context) { return TextButton( child: Text("Count is $count"), onPressed: () => setCount(count + 1), ); } } 4UBUFGVM8JEHFUͷઆ໌ JOJU4UBUFɿॳظԽͷॲཧ EJTQPTFɿഁغͷॲཧ TFU4UBUFɿݺͿ͜ͱͰঢ়ଶ͕มԽͨ͜͠ͱ Λ௨஌ͯ͠ϦϏϧυ͕૸Δ

Slide 14

Slide 14 text

4UBUFGVM8JEHFUͰ࣮૷ͨ͠৔߹ͷ՝୊ w ঢ়ଶΛอ࣋͢ΔΫϥεΛ৽ͨʹ࡞Βͳ͍ͱ͍͚ͳ͍ w ෳࡶͳϩδοΫΛؚΉঢ়ଶΛอ͍࣋ͨ͠৔߹ʹ͸ϩδοΫ ͱ΢ΟδΣοτΛ෼཭Ͱ͖͍ͯͳ͍ w ίʔυͷ࠶ར༻͕ѱ͍ w ςετ͕ॻ͖ʹ͍͘

Slide 15

Slide 15 text

'MVUUFS)PPLTͷ جຊΛཧղ͢Δ

Slide 16

Slide 16 text

'MVUUFS)PPLTͰԿ͕ղܾͰ͖Δ͔ ग़యɿIUUQTHJUIVCDPNSSPVTTFM(JU fl VUUFS@IPPLT ग़యɿIUUQTSFBDUKTPSHEPDTIPPLTJOUSPIUNM w એݴత6*ͰΫϥΠΞϯτΛ࣮૷্͍ͯ͘͠ͰɺϩδοΫͱ ΢ΟδΣοτʢίϯϙʔωϯτʣͷ෼཭ΛϝϯςφϯεੑΛอ ͪͭͭҡ࣋͢Δͷ͕೉͘͠ɺͦΕΛղܾ͢ΔػೳΛఏڙ͢Δ w ίϯϙʔωϯτΛͪΌΜͱؔ਺ͱͯ͠ѻ͏ͨΊ w ΫϥεͷఆٛΛݮΒ͢ʢγϯλοΫεγϡΨʔʣͨΊ w 'MVUUFSͷ΢ΟδΣοτ͸සൟʹ࠶ඳը͕࣮ߦ͞ΕΔͨΊॏ͍ ԋࢉ΍ෳࡶͳॲཧΛ͚͞ΕΔΑ͏ͳػೳΛఏڙ͢Δ w ಉ͡ೖྗσʔλͷ৔߹ʹ͸݁ՌΛΩϟογϡ͢Δ

Slide 17

Slide 17 text

VTF4UBUFΛཧղ͢Δ VTF4UBUF͸'MVUUFS)PPLTΛར༻͢ΔͳΒඞͣར༻͢Δ Ͱ͋Ζ͏جຊతͳϑοΫͰ͢ʢ಺෦࣮૷͸7BMVF/PUJGJFSʣ ར༻͢Δʹ֮͋ͨͬͯ͑Δ͜ͱ؆୯ͰVTF4UBUF 5 Ͱॳظ ஋Λ༩͑ɺDPVOUWBMVFͷ஋Λมߋ͢Δ͜ͱͰ࠶ඳը // ॳظԽ final count = useState(0); // ஋ͷߋ৽Λ࠶ඳը count.value = 3;

Slide 18

Slide 18 text

VTF4UBUFΛཧղ͢Δ ঢ়ଶͷ؅ཧΛ͢ΔͨΊʹϞόΠϧΞϓϦ։ൃͷΞʔΩςΫ νϟͰΑ͘ฉ͘Α͏ͳ7JFX.PEFM΍4UPSFΛ༻ҙ͢Δ΄ ͲͰ΋ͳ͍৔߹ʹར༻͢Δ͜ͱͰ͖Δ ྫ͑͹ɺϘλϯͷ&OBCMFE%JTBCMFEͷঢ়ଶͷอ࣋͸Θ͟ Θ͟ΫϥεΛ࡞Δ·Ͱ΋ͳ͘ɺͦͷ΢ΟδΣοτͰอ࣋͢ ΔͳͲ

Slide 19

Slide 19 text

VTF4UBUFΛཧղ͢Δ class CountPage extends HookWidget { @override Widget build(BuildContext context) { final count = useState(0); return TextButton( onPressed: () { count.value ++ ; }, child: Text("Count is ${count.value}"), ); } } class CountPage extends StatefulWidget { @override State createState() => _CountState(); } class _CountState extends State { int count = 0; void setCount(int value) => setState(() = > count = value); @override Widget build(BuildContext context) { return TextButton( child: Text("Count is $count"), onPressed: () => setCount(count + 1), ); } } 4UBUFGVM8JEHFU VTF4UBUF େ͖ͳҧ͍͸4UBUFΛܧঝͨ͠Ϋϥε͕ඞ ཁͩͬͨ΋ͷ͕ͳ͘ͳΓVTF4UBUF 5 ʹॳ ظ஋Λ༩͑Δ͚ͩʹͳ͍ͬͯΔ

Slide 20

Slide 20 text

VTF4UBUFΛཧղ͢Δ class CountPage extends HookWidget { @override Widget build(BuildContext context) { final count = useState(0); return TextButton( onPressed: () { count.value + + ; }, child: Text("Count is ${count.value}"), ); } }

Slide 21

Slide 21 text

VTF& ff FDUΛཧղ͢Δ ؆୯ͳ΢ΟδΣοτͷϥΠϑαΠΫϧͰॲཧ͕ඞཁͩͬͨ ৔߹ʹ͸VTF&GGFDUΛ࢖͏ 
 ʢ΢ΟδΣοτੜ੒࣌ʹॳظԽ΍ഁغΛ͍ͨ͠৔߹ͳͲʣ class _CountState extends State { ɹ // . .. @override void initState() { / ** ॳظԽ **/ } @override void dispose() { /** ഁغ **/ } } ɹ // . .. } 4UBUFGVM8JEHFUͷJOJU4UBUFEJQPTF૬౰

Slide 22

Slide 22 text

VTF& ff FDUΛཧղ͢Δ class CountPage extends HookWidget { @override Widget build(BuildContext context) { useEffect(() => { / / ॳظԽ final subscription = source.subscribe(id); return () => { // ഁغ subscription.unsubscribe(id); }; }, [id]); return // Widget . .. } } 8JEHFUͷCVJME಺ͰVTF&GGFDUͷୈҰҾ ਺ʹΫϩʔδϟΛ౉͠ɺͦͷΫϩʔδϟͷ SFUVSO࣌ʹഁغ࣌ͷॲཧΛॻ͘ VTF&GGFDUͷୈೋҾ਺ʹ͸ॳظԽΛϏϧυ࣌ ʹຖճ࣮ߦ͞Εͳ͍Α͏ʹΩʔͱͳΔΦϒ δΣΫτΛ౉͢ඞཁ͕͋Δ

Slide 23

Slide 23 text

VTF& ff FDUͷୈೋҾ਺͸ॏཁ class CountPage extends HookWidget { @override Widget build(BuildContext context) { useEffect(() => { / / ᶃ ID ͕มߋ͞ΕΔͨͼʹݺͼग़͠ }, [id]); useEffect(() => { / / ᶄ ຖճݺͼग़͠ }); useEffect(() => { / / ᶅ ࠷ॳͷҰճ͚ͩݺͼग़͠ }, const []); return // Widget . .. } }

Slide 24

Slide 24 text

VTF"OJNBUJPO$POUSPMMFSΛར༻ͯ͠ΈΔ class Example extends StatefulWidget { final Duration duration; const Example({Key? key, required this.duration}) : super(key: key); @override _ExampleState createState() => _ExampleState(); } class _ExampleState extends State with SingleTickerProviderStateMixin { AnimationController? _controller; @override void initState() { super.initState(); _controller = AnimationController(vsync: this, duration: widget.duration); } @override void didUpdateWidget(Example oldWidget) { super.didUpdateWidget(oldWidget); if (widget.duration != oldWidget.duration) { _controller!.duration = widget.duration; } } @override void dispose() { _controller!.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Container(); } } 4UBUFGVM8JEHFU 'MVUUFSͰΞχϝʔγϣϯΛ4UBUFGVM8JEHFU Ͱ࣮૷͠Α͏ͱ͢Δͱঢ়ଶ؅ཧͷίʔυΛΫ ϥεʹ͚ͩͰ͜Ε͚ͩඞཁʹͳΓͦͷଟ͕͘ ࢖͍ճ͠Ͱ͖ͳ͍ίʔυʹͳΔ ˞৑௕ͳίʔυΛݮΒ͢ͱ͍͏໨త͚ͩͰ͋ Ε͹%BSUʹ΋.JYJO͕͋ΔͷͰͦΕͰڞ௨ Խ͢Δ͜ͱ΋Ͱ͖Δ

Slide 25

Slide 25 text

VTF"OJNBUJPO$POUSPMMFSΛར༻ͯ͠ΈΔ class Example extends HookWidget { const Example({required this.duration}); final Duration duration; @override Widget build(BuildContext context) { final controller = useAnimationController(duration: duration); return Container(); } } class Example extends StatefulWidget { final Duration duration; const Example({Key? key, required this.duration}) : super(key: key); @override _ExampleState createState() => _ExampleState(); } class _ExampleState extends State with SingleTickerProviderStateMixin { AnimationController? _controller; @override void initState() { super.initState(); _controller = AnimationController(vsync: this, duration: widget.duration); } @override void didUpdateWidget(Example oldWidget) { super.didUpdateWidget(oldWidget); if (widget.duration != oldWidget.duration) { _controller!.duration = widget.duration; } } @override void dispose() { _controller!.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Container(); } } 4UBUFGVM8JEHFU VTF"OJNBUJPO$POUSPMMFS VTF"OJNBUJPO$POUSPMMFSΛ࢖͏͜ͱͰ৑௕ ͳίʔυྔ͸ݮΒ͢͜ͱ͕Ͱ͖ɺར༻ଆͰͷ ίετΛԼ͛Δ͜ͱ͕Ͱ͖Δ

Slide 26

Slide 26 text

'MVUUFS)PPLTͷ ޮՌతͳར༻๏

Slide 27

Slide 27 text

ΧελϜϑοΫΛ࡞੒͢Δ w ؔ਺໊ʹ͸VTF999ͱ͍͏໊લΛ͚ͭΔ w ࠷ॳ͸VTF4UBUF΍VTF& ff FDUΛ૊Έ߹Θ ࣮ͤͯ૷ͯ͠ΈΔ VoidCallback useUpdate() { final attempt = useState(0); return () => attempt.value ++ ; } class Sample extends HookWidget { @override Widget build(BuildContext context) { final update = useUpdate(); return Column( children: [ ElevatedButton( onPressed: () => update(), child: const Text("Update"), ), ] ); } } VTF6QEBUF 4BNQMF

Slide 28

Slide 28 text

fl VUUFS@VTFϥΠϒϥϦΛར༻ͯ͠ΈΔ w SFBDU@VTFͷ'MVUUFS൛ w Λ௒͑Δ৭ʑͳϢʔεέʔεʹରԠͨ͠ΧελϜϑοΫू w ࣗ࡞ΧελϜϑοΫΛ࡞Δͱ͖ʹࢀߟʹͰ͖Δʢͱࢥ͏ʣ

Slide 29

Slide 29 text

fl VUUFS@VTFϥΠϒϥϦΛར༻ͯ͠ΈΔ

Slide 30

Slide 30 text

VTF& ff FDU0ODFΛར༻ͯ͠ΈΔ w fl VUUFS@VTFʹ͓͍ͯ࠷΋୯७ͳ࣮૷ w VTF& ff FDUͷୈೋҾ਺Λলུ͢ΔͨΊͷΧελϜϑοΫ useEffect(() => { // ࠷ॳͷҰճ͚ͩݺͼग़͠ }, const []); void useEffectOnce(Dispose? Function() effect) { return useEffect(effect, const []); } VTF&GGFDU VTF&GGFDU0ODFͷ࣮૷

Slide 31

Slide 31 text

VTF& ff FDU0ODFΛར༻ͯ͠ΈΔ w fl VUUFS@VTFʹ͓͍ͯ࠷΋୯७ͳ࣮૷ w VTF& ff FDUͷୈೋҾ਺Λলུ͢ΔͨΊͷΧελϜϑοΫ useEffect(() => { // ࠷ॳͷҰճ͚ͩݺͼग़͠ }, const []); void useEffectOnce(Dispose? Function() effect) { return useEffect(effect, const []); } VTF&GGFDU VTF&GGFDU0ODFͷ࣮૷

Slide 32

Slide 32 text

w ΞϓϦཁ݅ͰԿඵޙʹॲཧΛ࣮ߦ͍ͤͨ͞৔߹ w VTF5JNFPVUVTF5JNFPVU'OΛ࢖͏͜ͱͰࢦఆͷ࣌ؒܦա ޙʹϦϏϧυ΍ΫϩʔδϟΛ࣮ߦ͢Δ͜ͱ͕Ͱ͖Δ class Sample extends HookWidget { @override Widget build(BuildContext context) { final timeout = useTimeout(const Duration(seconds: 3)); return Column( children: [ Text("isReady ?: ${timeout.isReady}"), ElevatedButton( onPressed: () => timeout.reset(), child: const Text("Reset"), ), ], ); } } VTF5JNFPVUΛར༻ͯ͠ΈΔ

Slide 33

Slide 33 text

w ಺෦Ͱ͸DPOOFDUJWJUZ@QMVTͱ͍͏ϥΠϒϥϦΛ࢖ͬͯ୺ ຤ͷωοτϫʔΫঢ়گΛऔಘ͍ͯ͠Δ w ࣗ෼Ͱ࣮૷͢Δͱඇಉظॲཧͷ੍ޚͳͲ͕ඞཁ͕ͩɺ͜ ͷΧελϜϑοΫͰ͸ར༻ଆ͸γϯϓϧʹ͍ͯ͠Δ class Sample extends HookWidget { @override Widget build(BuildContext context) { final networkState = useNetworkState(); return Column( children: [ Text( "Network: ${networkState.connectivityResult}"), ], ); } } VTF/FUXPSL4UBUFΛར༻ͯ͠ΈΔ

Slide 34

Slide 34 text

fl VUUFS@VTF IUUQTHJUIVCDPNXBTBCFFG fl VUUFS@VTF

Slide 35

Slide 35 text

ΧελϜϑοΫͷςετ w 'MVUUFS)PPLT5FTUJOH-JCSBSZΛར༻ͯ͠ΈΔ w SFBDUIPPLTUFTUJOHMJCSBSZͷ'MVUUFS൛

Slide 36

Slide 36 text

ϥΠϒϥϦΛར༻͠ͳ͍৔߹ testWidgets('usePrevious', (tester) async { await tester.pumpWidget( HookBuilder(builder: (context) { usePrevious(42); return const SizedBox(); }), ); await tester.pumpWidget( HookBuilder(builder: (context) { usePrevious(21); return const SizedBox(); }), ); final element = tester.element(find.byType(HookBuilder)); expect( element .toDiagnosticsNode(style: DiagnosticsTreeStyle.offstage) .toStringDeep(), equalsIgnoringHashCodes( 'HookBuilder\n' ' │ usePrevious: 42\n' ' └SizedBox(renderObject: RenderConstrainedBox#00000)\n', ), ); }); VTF1SFWJPVT͸'MVUUFS)PPLTʹඪ ४Ͱؚ·Ε͍ͯΔ༩͑ͨ஋ͷҰͭલͷ ঢ়ଶΛอ࣋͢ΔΧελϜϑοΫ ͜ͷϑοΫΛςετॻ͘৔߹ʹ͸࠷௿ Ͱ΋͜Ε͚ͩͷίʔυྔͰ͢

Slide 37

Slide 37 text

testWidgets('usePrevious', (tester) async { / / ... await tester.pumpWidget( HookBuilder(builder: (context) { usePrevious(42); return const SizedBox(); }), ); / / ... }); ϥΠϒϥϦΛར༻͠ͳ͍৔߹ গ͠ࡉ͔͘આ໌͍ͯ͘͠ͱɺ QVNQ8JEHFUͱ͍͏ςετ༻΢Ο δΣοτͷঢ়ଶΛ؅ཧ͍ͯ͠Δؔ਺ʹ )PPL#VJMEFSΛ౉ͯ͠ɺͦͷதͰΧε λϜϑοΫΛ࢖͏ඞཁ͕͋Δ

Slide 38

Slide 38 text

testWidgets('usePrevious', (tester) async { / / ... await tester.pumpWidget( HookBuilder(builder: (context) { usePrevious(21); return const SizedBox(); }), ); / / ... }); ϥΠϒϥϦΛར༻͠ͳ͍৔߹ ΋͏Ұ౓ߋ৽͠ͳ͍ͱ͍͚ͳ͍ͷͰɺ ઌ΄Ͳ͸͕ͩͬͨࠓճ͸Λ౉ ͍ͯ͠Δ

Slide 39

Slide 39 text

testWidgets('usePrevious', (tester) async { // .. . final element = tester.element(find.byType(HookBuilder)); expect( element .toDiagnosticsNode(style: DiagnosticsTreeStyle.offstage) .toStringDeep(), equalsIgnoringHashCodes( 'HookBuilder\n' ' │ usePrevious: 42\n' ' └SizedBox(renderObject: RenderConstrainedBox#00000)\n', ), ); // .. . }); VTF1SFWJPVTͱ͍͏Ұͭલͷ஋Λอ࣋ ͢ΔͷͰ࠷ॳʹ౉͕ͨ͠ݱࡏอ࣋ ͍ͯ͠Δ஋ͱͳΔ ͜ΕΛνΣοΫ͢ΔͨΊʹςετ΢Ο δΣοτͷϊʔυΛจࣈྻ͔Βϋο γϡίʔυͰൺֱ͍ͯ͠Δ ϥΠϒϥϦΛར༻͠ͳ͍৔߹

Slide 40

Slide 40 text

testWidgets('usePrevious', (tester) async { await tester.pumpWidget( HookBuilder(builder: (context) { usePrevious(42); return const SizedBox(); }), ); await tester.pumpWidget( HookBuilder(builder: (context) { usePrevious(21); return const SizedBox(); }), ); final element = tester.element(find.byType(HookBuilder)); expect( element .toDiagnosticsNode(style: DiagnosticsTreeStyle.offstage) .toStringDeep(), equalsIgnoringHashCodes( 'HookBuilder\n' ' │ usePrevious: 42\n' ' └SizedBox(renderObject: RenderConstrainedBox#00000)\n', ), ); }); ϥΠϒϥϦΛར༻͠ͳ͍৔߹

Slide 41

Slide 41 text

testWidgets('usePrevious', (tester) async { final result = await buildHook( (value) = > usePrevious(value), initialProps: 42, ); await result.rebuild(21); expect(result.current, 42); }); testWidgets('usePrevious', (tester) async { await tester.pumpWidget( HookBuilder(builder: (context) { usePrevious(42); return const SizedBox(); }), ); await tester.pumpWidget( HookBuilder(builder: (context) { usePrevious(21); return const SizedBox(); }), ); final element = tester.element(find.byType(HookBuilder)); expect( element .toDiagnosticsNode(style: DiagnosticsTreeStyle.offstage) .toStringDeep(), equalsIgnoringHashCodes( 'HookBuilder\n' ' │ usePrevious: 42\n' ' └SizedBox(renderObject: RenderConstrainedBox#00000)\n', ), ); }); ར༻͠ͳ͍ ར༻͢Δ ΧελϜϑοΫͷঢ়ଶΛߋ৽͢ΔͨΊʹ UFTUFSQVNQ8JEHFUʹ)PPL#VJMEFSΛຖ ճ౉͍ͯͨ͠΋ͷΛলུͰ͖ɺFYQFDU࣌ͷ ঢ়ଶऔಘ΋γϯϓϧʹॻ͚Δ ϥΠϒϥϦΛར༻͢Δ৔߹

Slide 42

Slide 42 text

testWidgets('usePrevious', (tester) async { final result = await buildHook( (value) = > usePrevious(value), initialProps: 42, ); await result.rebuild(21); expect(result.current, 42); }); 'MVUUFS)PPLT5FTUJOH-JCSBSZΛར༻ͨ͠৔ ߹͸ଟ͘ͷ৑௕ίʔυΛ࡟ݮ͢Δ͜ͱ͕Ͱ͖Δ CVJME)PPLɿͷΫϩʔδϟʹΧελϜϑοΫͷ ݺͼग़͠Λॻ͖ɺୈೋҾ਺ʹॳظ஋Λ༩͑Δ͜ ͱ͕Ͱ͖Δ SFCVJMEɿCVJME)PPLͰੜ੒͞ΕͨΫϥεͰ஋ Λߋ৽͠ϦϏϧυͰ͖Δ DVSSFOUɿอ͍࣋ͯ͠Δ஋ΛऔಘͰ͖Δ ϥΠϒϥϦΛར༻͢Δ৔߹

Slide 43

Slide 43 text

'MVUUFS)PPLT5FTUJOH-JCSBSZ IUUQTHJUIVCDPNXBTBCFFG fl VUUFS@IPPLT@UFTU

Slide 44

Slide 44 text

'MVUUFS)PPLTͷ-JOU w fl VUUFS@IPPLT@MJOU@QMVHJOΛར༻ͯ͠ΈΔ w FTMJOUQMVHJOSFBDUIPPLTͷ'MVUUFS൛ IUUQTHJUIVCDPNNKIE fl VUUFS@IPPLT@MJOU@QMVHJO

Slide 45

Slide 45 text

final variable1 = callSomething(); final variable2 = callSomething(); // ෆඞཁ·ͨ͸ෆ଍͍ͯ͠ΔΩʔ useEffect(() { print(variable1); }, [variable2]); // ϑοΫΛ৚݅෼ذͷதʹೖΕͳ͍ if (flag) { final variable = useState('hello'); } ϑοΫʹ͸͍͔ͭ͘ͷϧʔϧ͕͋Γ·͢ ྫ w ΧελϜϑοΫͷؔ਺໊ʹ͸VTF999 ͱ͍͏໊લΛ͚ͭΔ ɾϑοΫΛ৚݅෼ذʹೖΕͳ͍ ͜ͷ1MVHJOΛ࢖͏͜ͱͰόάΛ๷͙ͱڞ ʹϨϏϡʔͷίετͳͲͷԼ͛Δ fl VUUFS@IPPLT@MJOU@QMVHJOΛར༻ͯ͠ΈΔ

Slide 46

Slide 46 text

ࠓޙͷల๬

Slide 47

Slide 47 text

ࠓޙͷల๬ w )PPLTʹΑΔੈք؍Λ'MVUUFSք۾ʹਁಁ͍͖͍ͤͯͨ͞ w ੵۃతʹ'MVUUFSΑΓ΋ྺ࢙ͷ͋Δ3FBDU͔ΒऔΓೖΕ͍ͯ͘ w ྺ࢙͸3FBDUʼ'MVUUFSʼ+FUQBDL$PNQPTF4XJGU6*ͳͷͰ 'MVUUFSͷ஌ݟΛ+FUQBDL$PNQPTFͳͲʹ΋స༻͍ͯ͘͠ w 3FBDU2VFSZʹΑΔγϯϓϧͳઃܭΛ'MVUUFSʹ΋औΓೖΕ͍ͨ w ΞϓϦΞʔΩςΫνϟʹ࣌ؒΛ͔͚ͳ͍ੈք؍ͷ044࡞Δ w 3FDPJMɺ.77.ͳͲͷֶशʹ࣌ؒΛ࢖Θͣ؆୯ͳΞϓϦΛ؆୯ʹ࡞Δ ग़యɿIUUQTXXXJSBTVUPZBDPN