Kaede Hoshikawa 485a1b8c4a
Function Components & Hooks V2 (#2401)
* Make a use_hook hook with the new Hook trait.

* Implement Lifetime.

* Rewrites function signature.

* Only apply lifetime if there're other lifetimes.

* Cleanup signature rewrite logic.

* Rewrite hook body.

* Port some built-in hooks.

* Finish porting all built-in hooks.

* Port tests.

* Fix tests.

* Migrate to macro-based hooks.

* Fix HookContext, add tests on non-possible locations.

* Fix stderr for trybuild.

* Add 1 more test case.

* Adjust doc location.

* Pretty print hook signature.

* Fix Items & std::ops::Fn*.

* Add use_memo.

* Optimise Implementation of hooks.

* Use Box to capture function value only.

* Detect whether needs boxing.

* Add args if boxing not needed.

* Enforce hook number.

* Deduplicate use_effect.

* Optimise Implementation.

* Update documentation.

* Fix website test. Strip BoxedHook implementation from it.

* Allow doc string.

* Workaround doc tests.

* Optimise codebase & documentation.

* Fix website test.

* Reduce implementation complexity.

* Destructor is no more.

* Documentation and macros.

* Reduce heap allocation and hook complexity.

* Remove Queue as well.

* Prefer Generics.

* Fix typo.

* Remove more allocations.

* Add comments.

* Remove outdated comment.

* Bare Function Pointer for better code size.
2022-01-28 11:51:37 +02:00

72 lines
3.3 KiB
Plaintext

---
title: "Function Components"
sidebar_label: Introduction
description: "Introduction to function components "
---
Function components are a simplified version of normal components. They consist of a single function
that receives props and determines what should be rendered by returning `Html`. Basically, it's a
component that's been reduced to just the `view` method. On its own that would be quite limiting
because you can only create pure components, but that's where Hooks come in. Hooks allow function
components to maintain their own internal state and use other Yew features without needing to manually
implement the `Component` trait.
## Creating function components
The easiest way to create a function component is to add the [`#[function_component]`](./../function-components/attribute.mdx) attribute to a function.
```rust
use yew::{function_component, html, Html};
#[function_component]
fn HelloWorld() -> Html {
html! { "Hello world" }
}
```
### Under the hood
There are two parts to how Yew implements function components.
The first part is the `FunctionProvider` trait which is analogous to the `Component` trait, except
that it only has a single method (called `run`). The second part is the `FunctionComponent` struct
which wraps types implementing `FunctionProvider` and implements `Component`.
The `#[function_component]` attribute is a procedural macro which automatically implements
`FunctionProvider` for you and exposes it wrapped in `FunctionComponent`.
### Hooks
Hooks are functions that let you "hook into" components' state and/or lifecycle and perform
actions. Yew comes with a few pre-defined Hooks. You can also create your own.
Hooks can only be used at the following locations:
- Top level of a function / hook.
- If condition inside a function / hook, given it's not already branched.
- Match condition inside a function / hook, given it's not already branched.
- Blocks inside a function / hook, given it's not already branched.
#### Pre-defined Hooks
Yew comes with the following predefined Hooks:
- [`use_state`](./../function-components/pre-defined-hooks.mdx#use_state)
- [`use_state_eq`](./../function-components/pre-defined-hooks.mdx#use_state_eq)
- [`use_memo`](./../function-components/pre-defined-hooks.mdx#use_memo)
- [`use_mut_ref`](./../function-components/pre-defined-hooks.mdx#use_mut_ref)
- [`use_node_ref`](./../function-components/pre-defined-hooks.mdx#use_node_ref)
- [`use_reducer`](./../function-components/pre-defined-hooks.mdx#use_reducer)
- [`use_reducer_eq`](./../function-components/pre-defined-hooks.mdx#use_reducer_eq)
- [`use_effect`](./../function-components/pre-defined-hooks.mdx#use_effect)
- [`use_effect_with_deps`](./../function-components/pre-defined-hooks.mdx#use_effect_with_deps)
- [`use_context`](./../function-components/pre-defined-hooks.mdx#use_context)
#### Custom Hooks
There are cases where you want to define your own Hooks for reasons. Yew allows you to define your own Hooks which lets you extract your potentially stateful logic from the component into reusable functions.
See the [Defining custom hooks](./../function-components/custom-hooks.mdx#defining-custom-hooks) section for more information.
## Further reading
* The React documentation has a section on [React hooks](https://reactjs.org/docs/hooks-intro.html).
These are not exactly the same as Yew's hooks, but the underlying concept is similar.