Giter Club home page Giter Club logo

flhooks's Introduction

Build Status codecov

flhooks

Write stateful functional Component in Flutter. React like Hooks implementation for Flutter.

This package is inspired by React Hooks.

Why Hooks

Like for React, Hooks try to be a simple method to share stateful logic between Component.

The goal of thi library is to devoid class extensions and mixin. Of course flutter is not designed for functional Component and Hooks.

Getting Started

You should ensure that you add the flhooks as a dependency in your flutter project.

dependencies:
 flhooks: "^1.1.0"

You should then run flutter packages upgrade or update your packages in IntelliJ.

Rules

When using Hooks, React Hooks rules must be followed.

Only Call Hooks at the Top Level

Don’t call Hooks inside loops, conditions, or nested functions. Hooks can only be used inside a HookBuilder builder param. They can also be used to create other hooks.

Simple Usage

Hooks can only be used inside the builder of an HookBuilder.

HookBuilder is like a StatefulBuilder how build the builder function. Hooks function can be used only in the builder function.

// Define a Slider Page
final SliderPage = () =>
    HookBuilder(
      builder: (BuildContext context) {
        // define a state of type double
        final example = useState(0.0);
        final onChanged = useCallback((double newValue) {
          // change example.value for update the value in state
          example.value = newValue;
        }, [example]);
        return Material(
          child: Center(
            child: Slider(
              key: sliderKey,
              value: example.value,
              onChanged: onChanged,
            ),
          ),
        );
      },
    );
// Start the app
void main() =>
    runApp(MaterialApp(
      home: SliderPage(),
    ));

Hooks

Currently implemented Hooks.

useMemo

useMemo return the memoized result of the call to fn.

fn will be recalled only if store change.

 final helloMessage = useMemo(() => 'Hello ${name}', [name]);

useCallback

useCallback return the first reference to fn.

fn reference will change only if store change.

final onClick = useCallback(() => showAwesomeMessage(input1, input2),
  [input1, input2]);

It's the same as passing () => fn to useMemo.

useState

useState return a StateController, HookState.value is the initial value passed to useState, or the last set using state.value = newValue.

state.value = newValue will trigger the rebuild of the StatefulBuilder.

final name = useState('');
// ... get the value
  Text(name.value);
//... update the value and rebuild the component
  onChange: (newValue) => name.value = newValue;

useEffect

useEffect exec fn at first call or if store change. If fn return a function, this will be called if store change or when the widget dispose.

useEffect(() {
  final pub = stream.listen(callback);
  return () => pub.cancel();
  }, [stream]);

useEffect is useful for handle async or stream subscription.

Custom Hooks

Custom Hooks function can be created composing other hooks function.

Custom Hooks name must start with 'use'.

V useAsync<V>(Future<V> Function() asyncFn, V initial, List store) {
  final state = useState(initial);
  useEffect(() {
    var active = true;
    asyncFn().then((result) {
      if (active) {
        state.value = result;
      }
    });
    return () {
      active = false;
    };
  }, store);
  return state.value;
}

Now you can use useAsync like any other hooks function.

Hot Reload

Hot reload is basically supported.

When the hock type change, because an hook function is added, removed, or change type, the hook will be disposed and reset to null.

However after an add or a remove, all hooks after the one how change, can be disposed or had a reset.

Pay attention, will be no break after hot reloading the app, but will be other side effects.

We decide to not make hooks shift to the next position, because we prefer to have the same behavior in the case you add, remove, or change an hook function call.

Feel free to open a issue or fork the repository to suggest a new implementation.

Example

More example in the example directory.

Changelog

Current version is 1.1.0, read the changelog for more info.

Next on flhooks

New hooks will be added in future like useFuture (or useAsync) and useStream, there will be no need to use FutureBuilder and StreamBuilder anymore.

We are actually testing some useIf conditional implementation of hooks.

flhooks's People

Contributors

alfredosalzillo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar

flhooks's Issues

UseMemo(() => TextEditingController, []) not working

I tried using that same trick in the examples to obtain a TextEditingController but instead i'm getting an error, stack trace bellow:

Performing hot reload... ⡿I/flutter (28949): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════
I/flutter (28949): The following assertion was thrown building HookBuilder(dirty, state: _HookBuilderState#e2605):
I/flutter (28949): type 'Hook<TextEditingController, List>' is not a subtype of type 'Hook<HookState,
I/flutter (28949): List>'
I/flutter (28949):
I/flutter (28949): Either the assertion indicates an error in the framework itself, or we should provide substantially
I/flutter (28949): more information in this error message to help you determine and fix the underlying cause.
I/flutter (28949): In either case, please report this assertion by filing a bug on GitHub:
I/flutter (28949): https://github.com/flutter/flutter/issues/new?template=BUG.md
I/flutter (28949):
I/flutter (28949): When the exception was thrown, this was the stack:
I/flutter (28949): #0 use (package:flhooks/flhooks.dart:143:28)
I/flutter (28949): #1 useMemo (package:flhooks/flhooks.dart:157:10)
I/flutter (28949): #2 useState (package:flhooks/flhooks.dart:236:10)
I/flutter (28949): #3 _SearchPageState.build. (package:Capp/pages/searchPage.dart:15:30)
I/flutter (28949): #4 _HookBuilderState.build (package:flhooks/flhooks.dart:55:27)
I/flutter (28949): #5 StatefulElement.build (package:flutter/src/widgets/framework.dart:3809:27)
I/flutter (28949): #6 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3721:15)
I/flutter (28949): #7 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5)
I/flutter (28949): #8 StatefulElement.update (package:flutter/src/widgets/framework.dart:3878:5)
I/flutter (28949): #9 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15)
I/flutter (28949): #10 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3732:16)
I/flutter (28949): #11 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5)
I/flutter (28949): #12 StatefulElement.update (package:flutter/src/widgets/framework.dart:3878:5)
I/flutter (28949): #13 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15)
I/flutter (28949): #14 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3732:16)
I/flutter (28949): #15 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5)
I/flutter (28949): #16 StatelessElement.update (package:flutter/src/widgets/framework.dart:3781:5)
I/flutter (28949): #17 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15)
I/flutter (28949): #18 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3732:16)
I/flutter (28949): #19 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5)
I/flutter (28949): #20 StatelessElement.update (package:flutter/src/widgets/framework.dart:3781:5)
I/flutter (28949): #21 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15)
I/flutter (28949): #22 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3732:16)
I/flutter (28949): #23 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5)
I/flutter (28949): #24 ProxyElement.update (package:flutter/src/widgets/framework.dart:3990:5)
I/flutter (28949): #25 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15)
I/flutter (28949): #26 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4867:14)
I/flutter (28949): #27 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15)
I/flutter (28949): #28 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3732:16)
I/flutter (28949): #29 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5)
I/flutter (28949): #30 StatelessElement.update (package:flutter/src/widgets/framework.dart:3781:5)
I/flutter (28949): #31 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15)
I/flutter (28949): #32 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4867:14)
I/flutter (28949): #33 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15)
I/flutter (28949): #34 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3732:16)
I/flutter (28949): #35 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5)
I/flutter (28949): #36 StatelessElement.update (package:flutter/src/widgets/framework.dart:3781:5)
I/flutter (28949): #37 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15)
I/flutter (28949): #38 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4867:14)
I/flutter (28949): #39 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15)
I/flutter (28949): #40 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4867:14)
I/flutter (28949): #41 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15)
I/flutter (28949): #42 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4867:14)
I/flutter (28949): #43 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15)
I/flutter (28949): #44 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3732:16)
I/flutter (28949): #45 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5)
I/flutter (28949): #46 StatefulElement.update (package:flutter/src/widgets/framework.dart:3878:5)
I/flutter (28949): #47 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15)
I/flutter (28949): #48 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4867:14)
⣟I/flutter (28949): #49 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15)
I/flutter (28949): #50 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3732:16)
I/flutter (28949): #51 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5)
I/flutter (28949): #52 ProxyElement.update (package:flutter/src/widgets/framework.dart:3990:5)
I/flutter (28949): #53 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15)
I/flutter (28949): #54 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4867:14)
I/flutter (28949): #55 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15)
I/flutter (28949): #56 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3732:16)
I/flutter (28949): #57 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5)
I/flutter (28949): #58 StatefulElement.update (package:flutter/src/widgets/framework.dart:3878:5)
I/flutter (28949): #59 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15)
I/flutter (28949): #60 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3732:16)
I/flutter (28949): #61 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5)
I/flutter (28949): #62 StatelessElement.update (package:flutter/src/widgets/framework.dart:3781:5)
I/flutter (28949): #63 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15)
I/flutter (28949): #64 SingleChildRenderObjectElement.update (package:flutter/src/widgets/framework.dart:4867:14)
I/flutter (28949): #65 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15)
I/flutter (28949): #66 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3732:16)
I/flutter (28949): #67 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5)
I/flutter (28949): #68 ProxyElement.update (package:flutter/src/widgets/framework.dart:3990:5)
I/flutter (28949): #69 Element.updateChild (package:flutter/src/widgets/framework.dart:2742:15)
I/flutter (28949): #70 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3732:16)
I/flutter (28949): #71 Element.rebuild (package:flutter/src/widgets/framework.dart:3547:5)
I/flutter (28949): #72 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2286:33)
I/flutter (28949): #73 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding&WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:685:20)
I/flutter (28949): #74 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&SemanticsBinding&RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:219:5)
I/flutter (28949): #75 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:990:15)
I/flutter (28949): #76 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:930:9)
I/flutter (28949): #77 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.scheduleWarmUpFrame. (package:flutter/src/scheduler/binding.dart:751:7)
I/flutter (28949): #79 _Timer._runTimers (dart:isolate/runtime/libtimer_impl.dart:382:19)
I/flutter (28949): #80 _Timer._handleMessage (dart:isolate/runtime/libtimer_impl.dart:416:5)
I/flutter (28949): #81 _RawReceivePortImpl._handleMessage (dart:isolate/runtime/libisolate_patch.dart:171:12)
I/flutter (28949): (elided one frame from package dart:async)
I/flutter (28949): ════════════════════════════════════════════════════════════════════════════════════════════════════

Reloaded 0 of 563 libraries in 843ms.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.