Flutter扩展钩子功能插件flutter_hooks_extra的使用

Flutter扩展钩子功能插件flutter_hooks_extra的使用

flutter_hooks_extra

自定义钩子,基于flutter_hooks提供更高的可重用性。

useFutureState

管理异步数据的钩子。

useDebounceState

处理防抖值的钩子。

useEmitter

在多个小部件之间传递事件。通过使用useEmitter,可以简化这一过程。

useCounter

用于管理计数的钩子。

useCountdown

用于倒计时管理的钩子。


示例代码

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

// 模拟一个异步请求
Future _queryUserInfo(dynamic params) async {
  await Future.delayed(const Duration(milliseconds: 1000));
  return {'name': 'Tom', 'id': '$params'};
}

/// 使用useFutureState的示例
class HooksUseFutureStateDemo extends HookWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    // 使用useFutureState管理异步请求
    final queryUserInfoFuture = useFutureState(
      _queryUserInfo,
      options: FutureHookOptions(
        defaultParams: 1,
        loadingDelay: 3000,
      ),
    );

    return MaterialApp(
      title: 'HooksUseFutureStateDemo',
      home: Scaffold(
        appBar: AppBar(
          title: const Text('HooksUseFutureStateDemo'),
        ),
        body: Column(
          children: [
            if (queryUserInfoFuture.loading)
              const Text('loading')
            else
              Column(
                children: [
                  Text('${queryUserInfoFuture.data}'), // 显示请求结果
                  TextButton(
                    onPressed: () {
                      queryUserInfoFuture.run(2); // 刷新请求参数
                    },
                    child: const Text('user id: 2'),
                  ),
                ],
              ),
          ],
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () => queryUserInfoFuture.refresh(), // 手动刷新
          child: const Text('refresh'),
        ),
      ),
    );
  }
}

/// 使用useDebounceState的示例
class HooksUseDebounceStateDemo extends HookWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    // 使用useDebounceState处理防抖逻辑
    final debouncedValue = useDebounceState(0);

    return MaterialApp(
      title: 'HooksUseDebounceStateDemo',
      home: Scaffold(
        appBar: AppBar(
          title: const Text('HooksUseDebounceStateDemo'),
        ),
        body: Column(
          children: [Text('${debouncedValue.value}')], // 显示当前值
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            debouncedValue.value++; // 更新值
          },
          child: const Text('increment'),
        ),
      ),
    );
  }
}

/// 使用useEmitter的示例
class HooksUseEmitterDemo extends HookWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    // 使用useEmitter传递事件
    final emitter = useEmitter('demo');
    final num = useState(0);

    void addNumHandler(step) {
      num.value += step;
    }

    useEffect(() {
      // 添加事件监听器
      emitter.once('addNum', addNumHandler);
      return () {
        // 清除事件监听器
        emitter.off('addNum');
      };
    }, []);

    return MaterialApp(
      title: 'HooksUseEmitterDemo',
      home: Scaffold(
        appBar: AppBar(
          title: const Text('HooksUseEmitterDemo'),
        ),
        body: Column(
          children: [Text('${num.value}')], // 显示当前值
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            emitter.emit('addNum', 2); // 触发事件
          },
          child: const Text('emit'),
        ),
      ),
    );
  }
}

/// 使用useCounter的示例
class HooksUseCounterDemo extends HookWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    // 使用useCounter管理计数
    final counter = useCounter(0, step: 2, max: 10);

    return MaterialApp(
      title: 'HooksUseCounterDemo',
      home: Scaffold(
        appBar: AppBar(
          title: const Text('HooksUseCounterDemo'),
        ),
        body: Column(
          children: [
            Text('${counter.current}'), // 显示当前计数值
            TextButton(
              onPressed: counter.reset, // 重置计数
              child: const Text('Reset'),
            )
          ],
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: counter.inc, // 增加计数
          child: const Text('increment'),
        ),
      ),
    );
  }
}

/// 使用useCountdown的示例
class HooksUseCountDownDemo extends HookWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    // 使用useCountdown管理倒计时
    final countdown = useCountdown(DateTime(2022, 6, 30), onEnd: () {
      print('timesup!');
    });

    return MaterialApp(
      title: 'HooksUseCountDownDemo',
      home: Scaffold(
        appBar: AppBar(
          title: const Text('HooksUseCountDownDemo'),
        ),
        body: Column(
          children: [
            Text(
              '${countdown.formattedResult.days} / ${countdown.formattedResult.hours}:${countdown.formattedResult.minutes}:${countdown.formattedResult.seconds}',
            ), // 显示倒计时
          ],
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: () {
            countdown.setTarget(DateTime.now()); // 重新设置目标时间
          },
          child: const Text('End'),
        ),
      ),
    );
  }
}

void main() {
  runApp(HooksUseCountDownDemo());
  // runApp(HooksUseCounterDemo());
  // runApp(HooksUseEmitterDemo());
  // runApp(HooksUseDebounceStateDemo());
  // runApp(HooksUseFutureStateDemo());
}

更多关于Flutter扩展钩子功能插件flutter_hooks_extra的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter扩展钩子功能插件flutter_hooks_extra的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


flutter_hooks_extra 是一个 Flutter 插件,它扩展了 flutter_hooks 的功能,提供了更多的钩子(hooks)来简化状态管理和副作用处理。flutter_hooks 是 Flutter 中一个非常流行的库,它允许你在函数组件中使用类似于 React 的钩子来管理状态和副作用。

安装

首先,你需要在 pubspec.yaml 文件中添加 flutter_hooks_extra 依赖:

dependencies:
  flutter:
    sdk: flutter
  flutter_hooks: ^0.18.0
  flutter_hooks_extra: ^0.1.0

然后运行 flutter pub get 来安装依赖。

使用示例

flutter_hooks_extra 提供了许多额外的钩子,以下是一些常见的用法示例:

1. useDebouncedEffect

useDebouncedEffect 是一个用于防抖的钩子,它允许你在某个值变化后延迟执行副作用。

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

class DebouncedEffectExample extends HookWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    final text = useState('');

    useDebouncedEffect(
      () {
        print('Debounced text: ${text.value}');
      },
      [text.value],
      const Duration(seconds: 1),
    );

    return Scaffold(
      appBar: AppBar(title: Text('Debounced Effect Example')),
      body: Column(
        children: [
          TextField(
            onChanged: (value) => text.value = value,
            decoration: InputDecoration(labelText: 'Type something'),
          ),
          SizedBox(height: 20),
          Text('You typed: ${text.value}'),
        ],
      ),
    );
  }
}

在这个例子中,useDebouncedEffect 会在用户停止输入 1 秒后打印输入的文本。

2. useThrottledEffect

useThrottledEffect 是一个用于节流的钩子,它允许你在某个值变化后以固定的频率执行副作用。

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

class ThrottledEffectExample extends HookWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    final count = useState(0);

    useThrottledEffect(
      () {
        print('Throttled count: ${count.value}');
      },
      [count.value],
      const Duration(seconds: 1),
    );

    return Scaffold(
      appBar: AppBar(title: Text('Throttled Effect Example')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text('Count: ${count.value}'),
            ElevatedButton(
              onPressed: () => count.value++,
              child: Text('Increment'),
            ),
          ],
        ),
      ),
    );
  }
}

在这个例子中,useThrottledEffect 会在用户点击按钮后以每秒一次的频率打印计数器的值。

3. useAsyncEffect

useAsyncEffect 是一个用于处理异步副作用的钩子,它允许你在组件挂载或某个值变化时执行异步操作。

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

class AsyncEffectExample extends HookWidget {
  [@override](/user/override)
  Widget build(BuildContext context) {
    final data = useState<String?>(null);

    useAsyncEffect(
      () async {
        await Future.delayed(Duration(seconds: 2));
        data.value = 'Fetched data';
      },
      [],
    );

    return Scaffold(
      appBar: AppBar(title: Text('Async Effect Example')),
      body: Center(
        child: data.value == null
            ? CircularProgressIndicator()
            : Text(data.value!),
      ),
    );
  }
}
回到顶部