-
-
Notifications
You must be signed in to change notification settings - Fork 185
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Expanding the documentation #463
base: master
Are you sure you want to change the base?
Changes from all commits
aef338d
4a8a85b
13048ca
7b9e7d6
c953b72
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -17,13 +17,19 @@ bool debugHotReloadHooksEnabled = true; | |
// ignore: deprecated_member_use, deprecated_member_use_from_same_package | ||
R use<R>(Hook<R> hook) => Hook.use(hook); | ||
|
||
/// [Hook] is similar to a [StatelessWidget], but is not associated | ||
/// to an [Element]. | ||
/// Allows a [Widget] to create and access its own mutable data | ||
/// without implementing a [State]. | ||
/// | ||
/// A [Hook] is typically the equivalent of [State] for [StatefulWidget], | ||
/// with the notable difference that a [HookWidget] can have more than one [Hook]. | ||
/// A [Hook] is created within the [HookState.build] method of a [HookWidget] and the creation | ||
/// must be made unconditionally, always in the same order. | ||
/// Whereas [Widget]s store the immutable configuration for UI components, | ||
/// [Hook]s store immutable configuration for any type of object. | ||
/// The [HookState] of a [Hook] is analogous to the [State] of a [StatefulWidget], | ||
/// and a single [HookWidget] can use more than one [Hook]. | ||
/// | ||
/// Hooks can be used by replacing `extends StatelessWidget` with `extends HookWidget`, | ||
/// or by replacing `Builder()` with `HookBuilder()`. | ||
/// | ||
/// Hook functions must be called unconditionally during the `build()` method, | ||
/// and always in the same order. | ||
Comment on lines
-23
to
+32
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This makes sense, since you can go by the philosophy of "rather than making a State, make a Hook instead".
I believe this sentence was a typo: a |
||
/// | ||
/// ### Good: | ||
/// ``` | ||
|
@@ -216,7 +222,11 @@ Calling them outside of build method leads to an unstable state and is therefore | |
HookState<R, Hook<R>> createState(); | ||
} | ||
|
||
/// The logic and internal state for a [HookWidget] | ||
/// The logic and internal state of a [Hook]. | ||
/// | ||
/// This class is similar to a [State], but instead of building a [Widget] | ||
/// subtree, the [build] method can return a value of any type, as specified | ||
/// by the "result" type argument `R`. | ||
abstract class HookState<R, T extends Hook<R>> with Diagnosticable { | ||
/// Equivalent of [State.context] for [HookState] | ||
@protected | ||
|
@@ -277,22 +287,19 @@ abstract class HookState<R, T extends Hook<R>> with Diagnosticable { | |
|
||
/// Called before a [build] triggered by [markMayNeedRebuild]. | ||
/// | ||
/// If [shouldRebuild] returns `false` on all the hooks that called [markMayNeedRebuild] | ||
/// then this aborts the rebuild of the associated [HookWidget]. | ||
/// If [shouldRebuild] returns `false` on all the hooks that called [markMayNeedRebuild], | ||
/// [HookElement.build] will return a cached value instead of rebuilding each [Hook]. | ||
/// | ||
/// There is no guarantee that this method will be called after [markMayNeedRebuild] | ||
/// was called. | ||
/// Some situations where [shouldRebuild] will not be called: | ||
/// | ||
/// - [setState] was called | ||
/// - a previous hook's [shouldRebuild] returned `true` | ||
/// - the associated [HookWidget] changed. | ||
/// This method is not evaluated if a previous Hook called [markMayNeedRebuild] | ||
/// and its [shouldRebuild] method returned `true`. | ||
/// Additionally, if [setState], [didUpdateHook], or [HookElement.didChangeDependencies] is called, | ||
/// the build is unconditional and the `shouldRebuild()` call is skipped. | ||
bool shouldRebuild() => true; | ||
|
||
/// Mark the associated [HookWidget] as **potentially** needing to rebuild. | ||
/// | ||
/// As opposed to [setState], the rebuild is optional and can be cancelled right | ||
/// before `build` is called, by having [shouldRebuild] return false. | ||
/// before [build] is called, by having [shouldRebuild] return false. | ||
void markMayNeedRebuild() { | ||
if (_element!._isOptionalRebuild != false) { | ||
_element! | ||
|
@@ -368,7 +375,10 @@ extension on HookElement { | |
} | ||
} | ||
|
||
/// An [Element] that uses a [HookWidget] as its configuration. | ||
/// An [Element] that manages [Hook]s by storing the associated [HookState]s in a [LinkedList]. | ||
/// | ||
/// [use] and [useContext] can only be called during this element's [build] method. | ||
/// The `_buildCache` enables the behavior described in [HookState.shouldRebuild]. | ||
mixin HookElement on ComponentElement { | ||
static HookElement? _currentHookElement; | ||
|
||
|
@@ -576,14 +586,12 @@ Type mismatch between hooks: | |
} | ||
} | ||
|
||
/// A [Widget] that can use a [Hook]. | ||
/// A [Widget] that can use [Hook]s. | ||
Comment on lines
-579
to
+589
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. My hope was to tweak the wording here, so it's more explicit that you can use multiple Hooks. |
||
/// | ||
/// Its usage is very similar to [StatelessWidget]. | ||
/// [HookWidget] does not have any life cycle and only implements | ||
/// the [build] method. | ||
/// Similar to [StatelessWidget], a `HookWidget` is created by extending this class. | ||
/// | ||
/// The difference is that it can use a [Hook], which allows a | ||
/// [HookWidget] to store mutable data without implementing a [State]. | ||
/// The [HookWidget.build] method can [use] Hook functions, allowing this widget | ||
/// to store mutable data without implementing a [State]. | ||
abstract class HookWidget extends StatelessWidget { | ||
/// Initializes [key] for subclasses. | ||
const HookWidget({Key? key}) : super(key: key); | ||
|
@@ -596,12 +604,13 @@ class _StatelessHookElement extends StatelessElement with HookElement { | |
_StatelessHookElement(HookWidget hooks) : super(hooks); | ||
} | ||
|
||
/// A [StatefulWidget] that can use a [Hook]. | ||
/// A [StatefulWidget] that can use [Hook]s. | ||
/// | ||
/// Its usage is very similar to that of [StatefulWidget], but uses hooks inside [State.build]. | ||
/// Similar to [StatefulWidget], this widget creates a [State] which | ||
/// can store mutable data. | ||
/// | ||
/// The difference is that it can use a [Hook], which allows a | ||
/// [HookWidget] to store mutable data without implementing a [State]. | ||
/// The difference is that [Hook] functions can be called from within [State.build], | ||
/// similar to [HookWidget.build]. | ||
abstract class StatefulHookWidget extends StatefulWidget { | ||
/// Initializes [key] for subclasses. | ||
const StatefulHookWidget({Key? key}) : super(key: key); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought that "not associated to an Element" might lead to confusion, because much like a
StatefulWidget
,Hook
has acreateState()
method, and the object returned has access to thecontext
.