Flutter/pakages

Flutter Hooks ๋„ˆ๋ž€ ๋†ˆ์€ ๋ญ๋ƒ?! flutter_hooks ํŒŒํ—ค์ณ๋ณด๊ธฐ - useMemoized ์‚ฌ์šฉ๋ฒ• (2)

Hac. Dog ๐ŸŒญ 2024. 2. 13. 00:51

 

๋‘๋ฒˆ์งธ๋กœ๋Š” hook์— useMemoized function์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด์ž.

useMemoized์— ๋Œ€ํ•ด ๊ฐ„๋‹จํžˆ ์ด์•ผ๊ธฐ ํ•˜์ž๋ฉด, ๊ฐ’์„ ๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅํ•˜๊ณ  ์žˆ๋‹ค๊ฐ€

๊ฐ’์ด ๋ณ€ํ•œ๋‹ค๋ฉด ์žฌ๋นŒ๋“œ, ์•„๋‹ˆ๋ผ๋ฉด ์•„๋ฌด ๋ณ€ํ™”๋„ ์ฃผ์ง€ ์•Š๋Š”๋‹ค.

์ฆ‰ oldValue(๋ฉ”๋ชจ๋ฆฌ์— ์ €์žฅ๋œ ๊ฐ’)๊ณผ currentValue(ํ˜„์žฌ ๊ฐ’)๋ฅผ ๋‘๊ฐœ๋ฅผ ๊ณ„์† ๋น„๊ตํ•˜๋ฉด์„œ

์ƒํƒœ๋ฅผ ๋ณ€๊ฒฝํ•œ๋‹ค๊ณ  ์ดํ•ดํ•˜๋ฉด ์•„์ฃผ ์‰ฝ๊ฒŒ ์ดํ•ดํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ ์ด๋‹ค.

 

์ผ๋‹จ Implementation์— ๋Œ€ํ•ด์„œ ์•Œ์•„๋ณด์ž.

์ธ์ž๊ฐ’์œผ๋กœ Function ํ•จ์ˆ˜์™€ List<Object>๋ฅผ ๋ฐ›๋Š”๋‹ค.

 

๋‚˜๋Š” computerExpensiveOperation์ด๋ผ๋Š” ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค๊ณ  useMemorized๋กœ ์‹คํ–‰ํ•˜๋„๋ก ๊ตฌํ˜„ํ•˜์˜€๋‹ค.

int computerExpensiveOperation(int count) {
    print('useMemoized ํ•จ์ˆ˜ ์‹คํ–‰');
    // ์ƒ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๋น„์šฉ์ด ๋งŽ์ด ๋“œ๋Š” ์—ฐ์‚ฐ
    return count * count;
}
 

๊ทธ๋ฆฌ๊ณ  Widget ๋นŒ๋“œ์•ˆ์— useMemoried๋ฅผ ์„ค์ •ํ•˜์˜€๋‹ค.

Widget build(BuildContext context) {
   final counter = useState(0);
   final state = useState(0);
   // int expensiveValue = useMemoized(() => computeExpensiveOperation(state.value), [state.value]);
   int expensiveValue = useMemoized(() => computerExpensiveOperation(counter.value), [state.value]);
   	
   ... ๊ทธ์™ธ ์ฝ”๋“œ
}

๊ทธ๋ฆฌ๊ณ  floatingAction ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด๋ฉด state๊ฐ’์ด ๋ณ€ํ•˜๋„๋ก ๊ตฌํ˜„ํ•˜์˜€๋‹ค.

floatingActionButton: FloatingActionButton(
  onPressed: () {
    counter.value++;
    if (counter.value % 5 == 0) {
      // state.value;
      state.value++;
    }
  },

 

์ฆ‰ ์ฝ”๋“œ๋กœ ๊ฐ„๋‹จํžˆ ๋ณด๋ฉด,

counter๊ฐ’์ด 5์˜ ๋ฐฐ์ˆ˜์ผ ๊ฒฝ์šฐ์—๋Š” state๊ฐ’์„ ๋ณ€ํ™”์‹œํ‚จ๋‹ค.

๊ทธ๋ ‡๊ฒŒ ๋œ๋‹ค๋ฉด,

int expensiveValue = useMemoized(() => computerExpensiveOperation(counter.value), [state.value]);

๋ฅผ ํ†ตํ•ด์„œ ์ƒํƒœ๋ณ€ํ™”๊ฐ€ ๊ฐ์ง€๋˜๋Š” [state.value]๋ฅผ ํ†ตํ•ด state๊ฐ€ ๋ณ€๊ฒฝ๋˜์—ˆ์œผ๋ฏ€๋กœ computerExpensiveOperation ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋˜๊ณ 

int computerExpensiveOperation(int count) {
 print('useMemoized ํ•จ์ˆ˜ ์‹คํ–‰');
 // ์ƒ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๋น„์šฉ์ด ๋งŽ์ด ๋“œ๋Š” ์—ฐ์‚ฐ
 return count * count;
}

ํ•จ์ˆ˜๊ฐ€ ์‹คํ–‰๋˜๊ณ  expensiveValue ๋ณ€์ˆ˜์˜ ๊ฐ’์ด ๋ณ€๊ฒฝ์ด ๋˜๊ณ 

Text(
  'Sum : $expensiveValue',
  style: const TextStyle(
    fontSize: 32,
    fontWeight: FontWeight.bold,
  ),

๋ฅผ ํ†ตํ•ด์„œ Sumํ•จ์ˆ˜๊ฐ€ ์ตœ์ข…์ ์œผ๋กœ ๋ณด์—ฌ์ฃผ๊ฒŒ ๋œ๋‹ค.

 

์‹คํ–‰๋™์˜์ƒ์„ ํ†ตํ•ด์„œ ๊ฐ„๋‹จํ•˜๊ฒŒ ํ™•์ธํ•ด๋ณด์ž!

 

๊ทธ๋ ‡๋‹ค๋ฉด ์ด์ œ ์ด๋Ÿฐ ์ƒ๊ฐ์ด ๋“ค ์ˆ˜ ์žˆ๋‹ค.

 

useEffect๋ž‘ ๋ญ๊ฐ€ ๋‹ค๋ฅธ๊ฑฐ์•ผ? ๊ทผ๋ฐ ์™œ ์“ฐ๊ณ  ์–ด๋–ป๊ฒŒ ์‚ฌ์šฉํ•˜๋Š”๊ฑฐ์ง€?

 

์‚ฌ์‹ค ์ž˜ ๋ชจ๋ฅด๊ฒ ๋‹ค. useEffect๋„ useMemoried์ฒ˜๋Ÿผ ์“ธ ์ˆ˜ ์žˆ๋Š”๋ฐ ๋ฌด์—‡์ด ๋‹ค๋ฅธ ๊ฒƒ์ผ๊นŒ?

๊ฒฐ๊ตญ ์ฐจ์ด๋Š” ๋ฉ”๋ชจ๋ฆฌ์ €์žฅ์— ์žˆ๋Š” ๊ฒƒ ๊ฐ™๋‹ค. ๋˜๋Š” ๊ณ  ์—ฐ์‚ฐ์ฒ˜๋ฆฌ ์ž‘์—…์— ์“ฐ์ผ ์ˆ˜ ์žˆ์„ ๊ฒƒ ๊ฐ™๋‹ค.

์˜ˆ๋ฅผ๋“ค์–ด ํ•œ๊ฐ€์ง€ ์˜ˆ์‹œ๋กœ Future๋‚˜ Stream๊ฐ™์€ ์‹ค์‹œ๊ฐ„์œผ๋กœ ๊ณ„์†ํ•ด์„œ ๋“ค์–ด์˜ค๋Š” ๊ฐ’์ด ์žˆ๋‹ค๊ณ  ํ•˜์ž.

๊ทธ๋ ‡๋‹ค๋ฉด ๋งŒ์•ฝ ๋˜‘๊ฐ™์€ ๊ฐ’์ด ์‹ค์‹œ๊ฐ„์œผ๋กœ 1000๋ฒˆ ๋“ค์–ด์˜จ๋‹ค๊ณ  ํ•˜์ž ๊ทธ๋ ‡๋‹ค๋ฉด ๋ฐ์ดํ„ฐ ๊ฐ’์ด ๋˜‘๊ฐ™์œผ๋ฏ€๋กœ

์žฌ ๋นŒ๋“œ๋ฅผ ํ•˜์ง€ ์•Š๊ณ  ๋‹ค๋ฅธ ๊ฐ’์ด ๋“ค์–ด์™”์„ ๊ฒฝ์šฐ์—๋งŒ ๋นŒ๋“œ๋ฅผ ํ•  ๊ฒƒ ์ด๋‹ค.

๊ทผ๋ฐ ์‚ฌ์‹ค์ƒ ์„œ๋ฒ„์—์„œ ๋“ค์–ด์˜ค๋Š” ๊ฐ’์ด ๋˜‘๊ฐ™์€ ๊ฒฝ์šฐ๋Š” ๊ฑฐ์˜ ์—†์œผ๋‹ˆ... ์‹ค์ œ๋กœ ์‚ฌ์šฉํ• ์ง€๋Š” ์˜๋ฌธ์ด๊ธด ํ•˜๋‹ค.

 

๊ทธ๋ž˜์„œ ChatGpt์— ๋ฌผ์–ด๋ณด๋‹ˆ

 

๊ฒฐ๋ก ์ ์œผ๋กœ useMemoized๋Š” ๋ฉ”๋ชจ๋ฆฌํ™”๋ฅผ ํ†ตํ•œ ์žฌ๊ณ„์‚ฐ๋ฐฉ์ง€๊ฐ€ ๋ชฉ์ ์œผ๋กœ ๊ฐœ๋ฐœ๋œ ๊ฒƒ ๊ฐ™๋‹ค.

์ฆ‰ ๋ฆฌ์†Œ์Šค๊ฐ€ ๋งŽ์ด ํ•„์š”ํ•œ ๊ณ„์‚ฐ์ผ ๊ฒฝ์šฐ์—๋Š” useMemorized๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๊ฒŒ ์ข‹๋‹ค๋Š” ๊ฒƒ ๊ฐ™๋‹ค.

 

์ „์ฒด ์ฝ”๋“œ
์ฝ”๋“œ ๋ณด๊ธฐ
import 'dart:developer';

import 'package:flutter/material.dart';
import 'package:flutter_hooks/flutter_hooks.dart';

void main() {
  runApp(
    MaterialApp(
      debugShowCheckedModeBanner: false,
      home: HomeScreen(),
    ),
  );
}

// ignore: must_be_immutable
class HomeScreen extends HookWidget {
  HomeScreen({super.key});
  int value = 0;

  int computerExpensiveOperation(int count) {
    print('useMemoized ํ•จ์ˆ˜ ์‹คํ–‰');
    // ์ƒ์ƒํ•  ์ˆ˜ ์žˆ๋Š” ๋น„์šฉ์ด ๋งŽ์ด ๋“œ๋Š” ์—ฐ์‚ฐ
    return count * count;
  }

  @override
  Widget build(BuildContext context) {
    final counter = useState(0);
    final state = useState(0);
    // int expensiveValue = useMemoized(() => computeExpensiveOperation(state.value), [state.value]);
    int expensiveValue = useMemoized(() => computerExpensiveOperation(counter.value), [state.value]);

    log('Rebuild');
    return Scaffold(
      appBar: AppBar(
        title: const Text('useState'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(
              counter.value.toString(),
              style: const TextStyle(
                fontSize: 32,
                fontWeight: FontWeight.bold,
              ),
            ),
            Text(
              'Sum : $expensiveValue',
              style: const TextStyle(
                fontSize: 32,
                fontWeight: FontWeight.bold,
              ),
            ),
          ],
        ),
      ),
      floatingActionButton: FloatingActionButton(
        onPressed: () {
          counter.value++;
          if (counter.value % 5 == 0) {
            // state.value;
            state.value++;
          }
        },
        child: const Icon(Icons.add),
      ),
    );
  }
}