LoginSignup
3
2

More than 1 year has passed since last update.

フロントエンドエンジニアのための Flutter Hooks

Last updated at Posted at 2022-12-05

はじめに

Flutter Hooks は Flutter で React Hooks のように useState useEffect useCallback などのフックを使用できるライブラリです。
この記事では上記で挙げた3つのフックに焦点を当て、 Flutter Hooks と React Hooks の違いをまとめます。

useState

ローカルなステートを扱うためのフックです。
簡単なカウンターコンポーネント(カウンターウィジェット)を作成して違いを見ていきます。

React Hooks

参考: フック API リファレンス - useState

counter.jsx
import React, { useState } from 'react';

const Counter = () => {
  const [count, setCount] = useState(0);

  return (
    <div>
      <p>count: {count}</p>
      <button
        type="button"
        onClick={() => setCount((prev) => prev + 1)}
      >
        add
      </button>
    </div>
  );
};

Flutter Hooks

state.value で値にアクセスできます。また、値を更新するための関数は定義せず、 state.value の値を直接書き換えます。

参考: useState function

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

class Counter extends HookWidget {
  const Counter({super.key});

  @override
  Widget build(BuildContext context) {
    final count = useState(0);

    return Center(
      child: Column(
        mainAxisSize: MainAxisSize.min,
        children: [
          Text('count: ${count.value}'),
          TextButton(
            onPressed: () {
              count.value += 1;
            },
            child: const Text('add'),
          ),
        ],
      ),
    );
  }
}

useEffect

副作用を実行することを可能にするフックです。
先程のカウンターコンポーネントを使用し、コンソールに値を表示するようにします。

React Hooks

参考: フック API リファレンス - useEffect

counter.jsx
import React, { useState, useEffect } from 'react';

const Counter = () => {
  const [count, setCount] = useState(0);

  useEffect(() => {
    console.log(`count: ${count}`);
  }, [count]);

  return (
    ...
  );
};

Flutter Hooks

React Hooks と書きっぷりはほとんど同じですが、違う点もあります。

didMount & didUpdate are called after the render
initState & didUpdateWidget are called before the render

Similarly, when unmounting a Component tree, React will call willUnmount on parents first and go down the tree.
But Flutter does the opposite. It calls dispose on leaves first and goes up the tree.

引用: https://github.com/rrousselGit/flutter_hooks/issues/63#issuecomment-474994331

参考: useEffect function

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

class Counter extends HookWidget {
  const Counter({super.key});

  @override
  Widget build(BuildContext context) {
    final count = useState(0);

    useEffect(() {
      debugPrint('count: ${count.value}');

      return null;
    }, [count.value]);

    return ...
  }
}

useCallback

メモ化されたコールバックを返すフックです。
先程 useEffect 内で記述した処理を関数として定義します。

React Hooks

参考: フック API リファレンス - useCallback

counter.jsx
import React, { useState, useEffect, useCallback } from 'react';

const Counter = () => {
  const [count, setCount] = useState(0);

  const outputLog = useCallback(() => {
    console.log(`count: ${count}`);
  }, [count]);

  useEffect(() => {
    outputLog();
  }, [outputLog]);

  return (
    ...
  );
};

Flutter Hooks

useCallback に関しても書きっぷりはほとんど変わりません。
参考: useCallback function

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

class Counter extends HookWidget {
  const Counter({super.key});

  @override
  Widget build(BuildContext context) {
    final count = useState(0);

    final outputLog = useCallback(() {
      debugPrint('count: ${count.value}');
    }, [count.value]);

    useEffect(() {
      outputLog();
      
      return null;
    }, [outputLog]);

    return ...
  }
}

おわりに

今回 Flutter Hooks と React Hooks を比べてみましたが、ほとんど書き方に差はなく、どちらかの知識があればもう片方も書くことができるのが見て取れたと思います。今まではネイティブアプリを作成する際は React に慣れていることもあり、 React Native を用いることが多かったのですが、 Flutter Hooks を知ってからは Flutter でも同様に開発を行うことができるため選択肢の幅が広がったと思います。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2