mirror of
https://github.com/yewstack/yew.git
synced 2025-12-08 21:26:25 +00:00
Improve grammar and paragraph structure in documentation (#2620)
* Read through the docs and correct spelling and grammar * Run prettier * Apply review suggestions Co-authored-by: Muhammad Hamza <muhammadhamza1311@gmail.com> * adjust translation messages Co-authored-by: Muhammad Hamza <muhammadhamza1311@gmail.com>
This commit is contained in:
parent
c2b2f2cf2d
commit
cd5b8a520c
@ -1,3 +1,5 @@
|
||||
use std::cell::RefCell;
|
||||
|
||||
use instant::Instant;
|
||||
use person::PersonType;
|
||||
use web_sys::{HtmlElement, HtmlInputElement};
|
||||
@ -20,7 +22,6 @@ pub enum Msg {
|
||||
SortByAge,
|
||||
SortByAddress,
|
||||
ToggleKeyed,
|
||||
Rendered(Instant),
|
||||
}
|
||||
|
||||
pub struct App {
|
||||
@ -29,6 +30,7 @@ pub struct App {
|
||||
keyed: bool,
|
||||
build_component_ratio: f64,
|
||||
delta_ref: NodeRef,
|
||||
last_view: RefCell<Option<Instant>>,
|
||||
}
|
||||
|
||||
impl Component for App {
|
||||
@ -42,6 +44,7 @@ impl Component for App {
|
||||
keyed: true,
|
||||
build_component_ratio: 0.5,
|
||||
delta_ref: NodeRef::default(),
|
||||
last_view: RefCell::default(),
|
||||
}
|
||||
}
|
||||
|
||||
@ -122,22 +125,23 @@ impl Component for App {
|
||||
self.keyed = !self.keyed;
|
||||
true
|
||||
}
|
||||
Msg::Rendered(time_before) => {
|
||||
let time_after = Instant::now();
|
||||
let elapsed_max = time_after - time_before;
|
||||
log::info!("Rendering started {} ms ago.", elapsed_max.as_millis());
|
||||
if let Some(input) = self.delta_ref.cast::<HtmlElement>() {
|
||||
let delta_text =
|
||||
format!("The last rendering took {} ms", elapsed_max.as_millis());
|
||||
input.set_inner_text(&delta_text);
|
||||
}
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn rendered(&mut self, _ctx: &Context<Self>, _first_render: bool) {
|
||||
let time_after = Instant::now();
|
||||
let elapsed_max = time_after - self.last_view.get_mut().take().unwrap();
|
||||
log::info!("Rendering started {} ms ago.", elapsed_max.as_millis());
|
||||
let output = self.delta_ref.cast::<HtmlElement>().unwrap();
|
||||
let delta_text = format!("The last rendering took {} ms", elapsed_max.as_millis());
|
||||
output.set_inner_text(&delta_text);
|
||||
}
|
||||
|
||||
fn view(&self, ctx: &Context<Self>) -> Html {
|
||||
ctx.link().send_message(Msg::Rendered(Instant::now()));
|
||||
let mut last_view = self.last_view.borrow_mut();
|
||||
if last_view.is_none() {
|
||||
*last_view = Some(Instant::now());
|
||||
}
|
||||
|
||||
html! {
|
||||
<div class="container">
|
||||
|
||||
@ -6,7 +6,7 @@ description: "Yew's Actor System"
|
||||
import useBaseUrl from '@docusaurus/useBaseUrl'
|
||||
import ThemedImage from '@theme/ThemedImage'
|
||||
|
||||
Agents are a way to offload tasks to web workers or achieve inter-tab communication(WIP).
|
||||
Agents are a way to offload tasks to web workers.
|
||||
|
||||
In order for agents to run concurrently, Yew uses
|
||||
[web-workers](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API/Using_web_workers).
|
||||
|
||||
@ -7,16 +7,12 @@ comment: 'Keep this file as short and simple as possible. Its purpose is to ease
|
||||
import Tabs from '@theme/Tabs'
|
||||
import TabItem from '@theme/TabItem'
|
||||
|
||||
> Yew mostly operates on the idea of keeping everything that a reusable piece of
|
||||
> UI may need, in one place - rust files. But also seeks to stay close to the
|
||||
> original look of the technology.
|
||||
|
||||
Yew does not provide css in rs solutions natively, but helps with css by providing
|
||||
programmatic ways to interact with css classes.
|
||||
Yew does not natively provide a css in rust solution, but helps with styling by providing
|
||||
programmatic ways to interact with the html `class` attribute.
|
||||
|
||||
## Classes
|
||||
|
||||
The struct `Classes` simplifies use of HTML classes:
|
||||
The `classes!` macro and associated `Classes` struct simplify the use of HTML classes:
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="Literal" label="Literal">
|
||||
@ -25,7 +21,7 @@ The struct `Classes` simplifies use of HTML classes:
|
||||
use yew::{classes, html};
|
||||
|
||||
html! {
|
||||
<div class={classes!("container")}></div>
|
||||
<div class={classes!("container")}></div>
|
||||
};
|
||||
```
|
||||
|
||||
@ -91,7 +87,8 @@ We will expand upon this concept in [more CSS](../../more/css).
|
||||
|
||||
## Inline Styles
|
||||
|
||||
Currently Yew does not provide any help with inline styles natively:
|
||||
Currently Yew does not provide any special help with inline styles specified via the `styles` attribute,
|
||||
but you can use it like any other html attribute:
|
||||
|
||||
```rust
|
||||
use yew::{classes, html};
|
||||
|
||||
@ -7,82 +7,73 @@ comment: 'Keep this file as short and simple as possible. Its purpose is to ease
|
||||
import Tabs from '@theme/Tabs'
|
||||
import TabItem from '@theme/TabItem'
|
||||
|
||||
> Yew mostly operates on the idea of keeping everything that a reusable piece of
|
||||
> UI may need, in one place - rust files. But also seeks to stay close to the
|
||||
> original look of the technology.
|
||||
|
||||
For HTML we achieve this by providing the `html!` macro:
|
||||
You can write expressions resembling HTML with the `html!` macro. Behind the scenes Yew turns
|
||||
it into rust code representing the DOM to generate.
|
||||
|
||||
```rust
|
||||
use yew::prelude::*;
|
||||
|
||||
let my_header: Html = html!{<img src="img_girl.jpg" alt="Girl in a jacket" width="500" height="600" />};
|
||||
let my_header: Html = html! {
|
||||
<img src="img_girl.jpg" alt="Girl in a jacket" width="500" height="600" />
|
||||
};
|
||||
```
|
||||
|
||||
`html!` macro allows you to write html generation as if it was in a `.html` file and then behind the scenes by yew gets turned into internal builder patterns that generate all DOM nodes.
|
||||
|
||||
As it is part of rust code it provides a easy way to switch from html to rust by applying curly brackets:
|
||||
Similar to format expressions, there is an easy way to embed values from the surrounding
|
||||
context into the html by applying curly brackets:
|
||||
|
||||
```rust
|
||||
use yew::prelude::*;
|
||||
|
||||
let header_text = "Hello world".to_string();
|
||||
let header_html: Html = html!{<h1>{header_text}</h1>};
|
||||
let header_html: Html = html! {
|
||||
<h1>{header_text}</h1>
|
||||
};
|
||||
|
||||
let count: usize = 5;
|
||||
let counter_html: Html = html!{<p>{"My age is: "}{count}</p>};
|
||||
let counter_html: Html = html! {
|
||||
<p>{"My age is: "}{count}</p>
|
||||
};
|
||||
|
||||
let combined_html: Html = html!{<div>{header_html}{counter_html}</div>};
|
||||
let combined_html: Html = html! {
|
||||
<div>{header_html}{counter_html}</div>
|
||||
};
|
||||
```
|
||||
|
||||
One rule major rule comes with use of `html!` - you can only return 1 wrapping node:
|
||||
One rule major rule comes with use of `html!` - you can only return 1 wrapping node.
|
||||
To render a list of multiple elements, `html!` allows fragments. Fragments are tags
|
||||
without a name, that produce no html element by themselves.
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="Invalid" label="Invalid">
|
||||
|
||||
```rust , compile_fail
|
||||
use yew::html;
|
||||
|
||||
// error: only one root html element allowed
|
||||
html! {
|
||||
|
||||
<div></div>
|
||||
<p></p>
|
||||
|
||||
};
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="Valid" label="Valid">
|
||||
|
||||
```rust
|
||||
use yew::html;
|
||||
|
||||
html! {
|
||||
<div>
|
||||
<div></div>
|
||||
<p></p>
|
||||
</div>
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
|
||||
<TabItem value="Invalid" label="Invalid">
|
||||
|
||||
```rust, compile_fail
|
||||
use yew::html;
|
||||
|
||||
// error: only one root html element allowed
|
||||
|
||||
html! {
|
||||
<div></div>
|
||||
<p></p>
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
To help with this rule and avoid `div` abuse `html!` allows fragments. Fragments are empty tags that do not provide any html result:
|
||||
|
||||
```rust
|
||||
use yew::html;
|
||||
|
||||
// fixed: using html fragments
|
||||
html! {
|
||||
<>
|
||||
<div></div>
|
||||
<p></p>
|
||||
</>
|
||||
};
|
||||
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
We will introduce Yew and HTML further in depth in [more HTML](concepts/html/introduction.mdx).
|
||||
|
||||
@ -7,19 +7,18 @@ comment: 'Keep this file as short and simple as possible. Its purpose is to ease
|
||||
import Tabs from '@theme/Tabs'
|
||||
import TabItem from '@theme/TabItem'
|
||||
|
||||
> Yew mostly operates on the idea of keeping everything that a reusable piece of
|
||||
> UI may need, in one place - rust files. But also seeks to stay close to the
|
||||
> original look of the technology.
|
||||
> Yew centrally operates on the idea of keeping everything that a reusable piece of
|
||||
> UI may need in one place - rust files, while also keeping the underlying technology
|
||||
> accessible where necessary.
|
||||
|
||||
Sadly as of today WebAssembly is not feature-complete for DOM interactions. This means even in Yew we sometimes rely on calling Javascript.
|
||||
As of today, WebAssembly is not feature-complete for DOM interactions. This means even in Yew we
|
||||
sometimes rely on calling Javascript. What follows is an overview of the involved libraries.
|
||||
|
||||
## wasm-bindgen
|
||||
|
||||
[`wasm-bindgen`](https://github.com/rustwasm/wasm-bindgen) is a library and tool that allows to call javascript from rust and rust from javascript.
|
||||
[`wasm-bindgen`](https://github.com/rustwasm/wasm-bindgen) is a library and tool that enables calls to javascript from rust and back to rust from javascript.
|
||||
|
||||
We highly recommend you give a look to their [documentation](https://rustwasm.github.io/docs/wasm-bindgen/)
|
||||
|
||||
We will also expand upon this concept in the [more wasm-bindgen](../wasm-bindgen).
|
||||
We highly recommend you take a look at their [documentation](https://rustwasm.github.io/docs/wasm-bindgen/) and our [quick guide](./wasm-bindgen.mdx).
|
||||
|
||||
## web-sys
|
||||
|
||||
@ -51,6 +50,4 @@ let document = window()
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
Once again we highly recommend you give a look to their [documentation](https://rustwasm.github.io/docs/wasm-bindgen/)
|
||||
|
||||
We will also expand upon this concept in the [more wasm-bindgen](../wasm-bindgen).
|
||||
Once again we highly recommend you take a look at their [documentation](https://rustwasm.github.io/docs/wasm-bindgen/) and our [quick guide](./web-sys.mdx).
|
||||
|
||||
@ -103,7 +103,7 @@ its own section below.
|
||||
|
||||
_[extends section in The `wasm-bindgen` Guide](https://rustwasm.github.io/docs/wasm-bindgen/reference/attributes/on-js-imports/extends.html)_
|
||||
|
||||
### [`JsValue`](https://rustwasm.github.io/wasm-bindgen/api/wasm_bindgen/struct.JsValue.html)
|
||||
### [`JsValue`](https://rustwasm.github.io/wasm-bindgen/api/wasm_bindgen/struct.JsValue.html) {#jsvalue}
|
||||
|
||||
This is a representation of an object owned by JavaScript, this is a root catch-all type for `wasm-bindgen`.
|
||||
Any type that comes from `wasm-bindgen` is a `JsValue` and this is because JavaScript doesn't have
|
||||
@ -117,7 +117,7 @@ being imported as to whether an exception (panic) will be raised if that value i
|
||||
|
||||
_[`JsValue` documentation](https://rustwasm.github.io/wasm-bindgen/api/wasm_bindgen/struct.JsValue.html)._
|
||||
|
||||
### [`JsCast`](https://rustwasm.github.io/wasm-bindgen/api/wasm_bindgen/trait.JsCast.html)
|
||||
### [`JsCast`](https://rustwasm.github.io/wasm-bindgen/api/wasm_bindgen/trait.JsCast.html) {#JsCast}
|
||||
|
||||
Rust has a strong type system and JavaScript...doesn't 😞. In order for Rust to maintain these
|
||||
strong types but still be convenient the WebAssembly group came up with a pretty neat trait `JsCast`.
|
||||
@ -18,13 +18,13 @@ exposes some types in it's public API, you will often need to add `web-sys` as a
|
||||
|
||||
## Inheritance in `web-sys`
|
||||
|
||||
In the [Simulating inheritance section](../wasm-bindgen#simulating-inheritance) you can read how in
|
||||
In the [Simulating inheritance section](./wasm-bindgen.mdx#simulating-inheritance) you can read how in
|
||||
general Rust provides an approach to simulate inheritance in JavaScript. This is very important in
|
||||
`web-sys` as understanding what methods are available on a type means understanding it's inheritance.
|
||||
|
||||
This section is going to look at a specific element and list out it's inheritance using Rust by
|
||||
calling [`Deref::deref`](https://doc.rust-lang.org/std/ops/trait.Deref.html#tymethod.deref) until
|
||||
the value is [`JsValue`](../wasm-bindgen/introduction.mdx#jsvalue):
|
||||
the value is [`JsValue`](./wasm-bindgen.mdx#jsvalue):
|
||||
|
||||
```rust
|
||||
use std::ops::Deref;
|
||||
@ -84,7 +84,7 @@ a `Node` made by the [`html!`](concepts/html/introduction.mdx) macro. The `Node`
|
||||
[`web_sys::Node`](https://rustwasm.github.io/wasm-bindgen/api/web_sys/struct.Node.html). The
|
||||
`NodeRef::get` method will return a `Option<Node>` value, however, most of the time in Yew you want
|
||||
to cast this value to a specific element so you can use it's specific methods. This casting
|
||||
can be done using [`JsCast`](../wasm-bindgen#JsCast) on the `Node` value, if present, but Yew
|
||||
can be done using [`JsCast`](./wasm-bindgen.mdx#JsCast) on the `Node` value, if present, but Yew
|
||||
provides the `NodeRef::cast` method to perform this casting for convenience and so that you don't
|
||||
necessarily have to include the `wasm-bindgen` dependency for the `JsCast` trait.
|
||||
|
||||
@ -2,10 +2,10 @@
|
||||
title: 'Callbacks'
|
||||
---
|
||||
|
||||
Callbacks used to asynchronously communicate in Yew upwards the components tree and other things like agents or DOM.
|
||||
Internally their type is just `Fn` wrapped in `Rc` to allow them to be cloned. You will need to clone them often.
|
||||
Callbacks are used to asynchronously communicate upwards the components tree and with other things like agents or the DOM during event handling.
|
||||
Internally their type is just an `Fn` wrapped in `Rc` to allow them to be cheaply cloned.
|
||||
|
||||
They have an `emit` function that takes their `<IN, OUT = ()>` types as an arguments.
|
||||
They have an `emit` function if you want to call them manually.
|
||||
|
||||
```rust
|
||||
use yew::{html, Component, Context, Html, Callback};
|
||||
@ -46,7 +46,7 @@ fn App() -> Html {
|
||||
// web_sys::console::log_1(&greeting.into()); // if uncommented will print
|
||||
});
|
||||
|
||||
html! {<HelloWorld {on_name_entry} />}
|
||||
html! { <HelloWorld {on_name_entry} /> }
|
||||
}
|
||||
|
||||
```
|
||||
@ -55,7 +55,7 @@ fn App() -> Html {
|
||||
|
||||
Callbacks are also used to hook into DOM events.
|
||||
|
||||
For example here we define a callback that will be called when user clicks the button:
|
||||
For example here we define a callback that will be called when the user clicks the button:
|
||||
|
||||
```rust
|
||||
use yew::{function_component, html, Html, Properties, Callback};
|
||||
@ -67,6 +67,8 @@ fn App() -> Html {
|
||||
// web_sys::console::log_1(&greeting.into()); // if uncommented will print
|
||||
});
|
||||
|
||||
html! {<button {onclick}>{ "Click" }</button>}
|
||||
html! {
|
||||
<button {onclick}>{ "Click" }</button>
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
title: 'Children'
|
||||
---
|
||||
|
||||
`Children` is a special prop type that allows you to take what was provided as `Html` children.
|
||||
`Children` is a special prop type that allows you to recieve nested `Html` that is provided like html child elements.
|
||||
|
||||
```rust
|
||||
use yew::{function_component, html, Html, Properties, Children};
|
||||
@ -22,7 +22,7 @@ fn App() -> Html {
|
||||
#[derive(Properties, PartialEq)]
|
||||
pub struct Props {
|
||||
// highlight-next-line
|
||||
pub children: Children,
|
||||
pub children: Children, // the field name `children` is important!
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
@ -30,11 +30,10 @@ fn HelloWorld(props: &Props) -> Html {
|
||||
html! {
|
||||
<div class="very-stylized-container">
|
||||
// highlight-next-line
|
||||
{ for props.children.iter() } //then use like this
|
||||
{ for props.children.iter() } // you can forward children like this
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
||||
```
|
||||
|
||||
## Further reading
|
||||
|
||||
@ -4,7 +4,7 @@ title: 'Custom Hooks'
|
||||
|
||||
## Defining custom Hooks
|
||||
|
||||
Component's stateful logic can be extracted into usable function by creating custom Hooks
|
||||
Component's stateful logic can be extracted into reusable function by creating custom Hooks.
|
||||
|
||||
Consider that we wish to create an event listener that listens to an event on the `window`
|
||||
object.
|
||||
@ -35,11 +35,11 @@ pub fn show_storage_changed() -> Html {
|
||||
|
||||
There's one problem with this code: the logic can't be reused by another component.
|
||||
If we build another component which keeps track of the an event,
|
||||
instead of copying the code we can move the logic into a custom hook.
|
||||
instead of copying the code, we can move the logic into a custom hook.
|
||||
|
||||
We'll start by creating a new function called `use_event`.
|
||||
The `use_` prefix denotes that a function is a hook.
|
||||
This function will take an event target, a event type and a callback.
|
||||
This function will take an event target, an event type and a callback.
|
||||
All hooks must be marked by `#[hook]` to function as as hook.
|
||||
|
||||
```rust
|
||||
@ -58,8 +58,8 @@ where
|
||||
}
|
||||
```
|
||||
|
||||
This is a simple hook which can be created by using built-in hooks. For this example, we'll use the `use_effect_with_deps` hook,
|
||||
which subscribes to the dependencies so an event listener can be recreated when hook arguments change.
|
||||
This is a simple hook which can be created by composing built-in hooks. For this example, we'll use the
|
||||
`use_effect_with_deps` hook, so an event listener can be recreated when the hook arguments change.
|
||||
|
||||
```rust
|
||||
use yew::prelude::*;
|
||||
@ -72,28 +72,19 @@ use gloo::events::EventListener;
|
||||
pub fn use_event<E, F>(target: &EventTarget, event_type: E, callback: F)
|
||||
where
|
||||
E: Into<Cow<'static, str>>,
|
||||
F: Fn(&Event) + 'static,
|
||||
F: Fn(Event) + 'static,
|
||||
{
|
||||
#[derive(Clone)]
|
||||
#[derive(PartialEq, Clone)]
|
||||
struct EventDependents {
|
||||
target: EventTarget,
|
||||
event_type: Cow<'static, str>,
|
||||
callback: Rc<dyn Fn(&Event)>,
|
||||
}
|
||||
|
||||
#[allow(clippy::vtable_address_comparisons)]
|
||||
impl PartialEq for EventDependents {
|
||||
fn eq(&self, rhs: &Self) -> bool {
|
||||
self.target == rhs.target
|
||||
&& self.event_type == rhs.event_type
|
||||
&& Rc::ptr_eq(&self.callback, &rhs.callback)
|
||||
}
|
||||
callback: Callback<Event>,
|
||||
}
|
||||
|
||||
let deps = EventDependents {
|
||||
target: target.clone(),
|
||||
event_type: event_type.into(),
|
||||
callback: Rc::new(callback) as Rc<dyn Fn(&Event)>,
|
||||
callback: Callback::from(callback),
|
||||
};
|
||||
|
||||
use_effect_with_deps(
|
||||
@ -105,7 +96,7 @@ where
|
||||
} = deps.clone();
|
||||
|
||||
let listener = EventListener::new(&target, event_type, move |e| {
|
||||
callback(e);
|
||||
callback.emit(e.clone());
|
||||
});
|
||||
|
||||
move || {
|
||||
|
||||
@ -12,14 +12,14 @@ Yew comes with a few pre-defined Hooks. You can also create your own or discover
|
||||
## Rules of hooks
|
||||
|
||||
1. A hook function name always has to start with `use_`
|
||||
2. Hooks can only be used at the following locations:
|
||||
2. Hooks can only be used in 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.
|
||||
3. Hooks every render must be called in the same order
|
||||
- In the condition of a top level `if` expression inside a function / hook.
|
||||
- In the scrutinee of a top level `match` expression inside a function / hook.
|
||||
3. Hooks must be called in the same order for every render. Returning early is only allowed when using [Suspense](../../suspense.mdx)
|
||||
|
||||
All these rules are enforced by either compile time or run-time errors.
|
||||
These rules are enforced by either compile time or run-time errors.
|
||||
|
||||
### Pre-defined Hooks
|
||||
|
||||
@ -40,7 +40,7 @@ Yew comes with the following predefined Hooks:
|
||||
|
||||
### 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.
|
||||
There are cases where you want to define your own Hooks to encapsulate potentially stateful logic from a component into reusable functions.
|
||||
See the [Defining custom hooks](concepts/function-components/hooks/custom-hooks.mdx#defining-custom-hooks) section for more information.
|
||||
|
||||
## Further reading
|
||||
|
||||
@ -4,7 +4,7 @@ title: 'use_callback'
|
||||
|
||||
`use_callback` is used for obtaining an immutable reference to a memoized `Callback`.
|
||||
Its state persists across renders.
|
||||
It will be recreated only if any of the dependencies values change.
|
||||
It will be recreated only if any of the dependencies changes value.
|
||||
|
||||
`use_callback` can be useful when passing callbacks to optimized child components that rely on
|
||||
PartialEq to prevent unnecessary renders.
|
||||
|
||||
@ -2,8 +2,6 @@
|
||||
title: 'use_context'
|
||||
---
|
||||
|
||||
[Contexts](../../contexts.mdx) will be introduced later.
|
||||
|
||||
`use_context` is used for consuming [contexts](../../contexts.mdx) in function components.
|
||||
|
||||
## Example
|
||||
|
||||
@ -6,7 +6,8 @@ title: 'use_effect'
|
||||
|
||||
It takes a function which is called every time after the component's render has finished.
|
||||
|
||||
The input function has to return a closure - a cleanup function, which is called right before starting a new render.
|
||||
The input function has to return a closure - a cleanup function, which is called right
|
||||
before starting a new render or when the component unmounts.
|
||||
|
||||
## Example
|
||||
|
||||
@ -42,11 +43,8 @@ fn EffectExample() -> Html {
|
||||
|
||||
`use_effect_with_deps` is a more enhanced version of [`use_effect`](#use_effect).
|
||||
|
||||
It takes a second argument - dependencies.
|
||||
|
||||
Only when dependencies change, it calls the provided function.
|
||||
|
||||
Same way with the clean-up function - it gets called only before re-calling the function from the first argument.
|
||||
It takes a second argument - dependencies. The effect is only executed - and the
|
||||
old effect cleaned up - when the dependencies change compared to the previous call.
|
||||
|
||||
:::note
|
||||
|
||||
@ -81,9 +79,10 @@ fn HelloWorld(props: &Props) -> Html {
|
||||
|
||||
## Tips
|
||||
|
||||
### Only on first render
|
||||
### Only on first render {#only-on-first-render}
|
||||
|
||||
Provide a empty tuple `()` as dependencies when you need to do something only on first render.
|
||||
Provide a empty tuple `()` as dependencies when you need to do something only on the first render
|
||||
of a component.
|
||||
|
||||
```rust
|
||||
use yew::{function_component, html, Html, use_effect_with_deps};
|
||||
@ -106,7 +105,7 @@ fn HelloWorld() -> Html {
|
||||
|
||||
### On destructing or last render
|
||||
|
||||
Use [Only on first render](#only-on-first-render) and write the code in the cleanup function.
|
||||
Use [Only on first render](#only-on-first-render) but put the code in the cleanup function.
|
||||
It will only get called when the component is removed from view / gets destroyed.
|
||||
|
||||
```rust
|
||||
@ -116,8 +115,7 @@ use yew::{function_component, html, Html, use_effect_with_deps};
|
||||
fn HelloWorld() -> Html {
|
||||
use_effect_with_deps(
|
||||
move |_| {
|
||||
// move is not needed bellow but the docs page breaks without it
|
||||
move || {
|
||||
|| {
|
||||
web_sys::console::log_1(&"Noo dont kill me, ahhh!".into());
|
||||
}
|
||||
},
|
||||
@ -126,35 +124,3 @@ fn HelloWorld() -> Html {
|
||||
html! { "Hello" }
|
||||
}
|
||||
```
|
||||
|
||||
### Applying event listeners to the DOM
|
||||
|
||||
Generally you can directly add the `on` + event name as just a html attribute.
|
||||
|
||||
But for cases when you need to do it manually always re-apply and destroy old event listeners every render to avoid duplicate listeners in the DOM.
|
||||
|
||||
Same tip applies to intervals and timeouts.
|
||||
|
||||
```rust
|
||||
use yew::{function_component, html, Html, use_effect_with_deps, use_node_ref};
|
||||
|
||||
#[function_component]
|
||||
fn HelloWorld() -> Html {
|
||||
let span_ref = use_node_ref();
|
||||
|
||||
{
|
||||
let span_ref = span_ref.clone();
|
||||
use_effect_with_deps(
|
||||
move |_| {
|
||||
let listener = gloo::events::EventListener::new(&span_ref.cast::<web_sys::HtmlElement>().unwrap(), "click", move |event| {
|
||||
web_sys::console::log_1(&"I got clicked".into());
|
||||
});
|
||||
move || drop(listener)
|
||||
},
|
||||
(),
|
||||
);
|
||||
}
|
||||
|
||||
html! {<span ref={span_ref}>{"Hello"}</span>}
|
||||
}
|
||||
```
|
||||
|
||||
@ -6,11 +6,9 @@ title: 'use_force_update'
|
||||
Usually, this re-render is triggered automatically by the hook holding your data, for example when
|
||||
changing the data in a handle returned from [`use_state`](./use-state).
|
||||
|
||||
::: caution
|
||||
|
||||
:::caution
|
||||
Often, using this hook means you are doing something wrong and should use one of the other hooks,
|
||||
for example [`use_reducer`](./use-reducer) is a great way to track changing data.
|
||||
|
||||
for example [`use_reducer`](./use-reducer) is another great way to track changing data.
|
||||
:::
|
||||
|
||||
Use this hook when wrapping an API that doesn't expose precise subscription events for fetched data.
|
||||
|
||||
@ -4,7 +4,7 @@ title: 'use_memo'
|
||||
|
||||
`use_memo` is used for obtaining an immutable reference to a memoized value.
|
||||
Its state persists across renders.
|
||||
Its value will be recalculated only if any of the dependencies values change.
|
||||
Its value will be recalculated only if any of the dependencies changes value.
|
||||
|
||||
`use_memo` can be useful for keeping things in scope for the lifetime of the component, so long as
|
||||
you don't store a clone of the resulting `Rc` anywhere that outlives the component.
|
||||
|
||||
@ -2,7 +2,11 @@
|
||||
title: 'use_node_ref'
|
||||
---
|
||||
|
||||
`use_node_ref` is used for maintaining an easy reference to the DOM element represented as a `NodeRef`. It also persists across renders.
|
||||
`use_node_ref` is used for maintaining a reference to a DOM element represented as a
|
||||
[`NodeRef`](../node-refs.mdx). It also persists across renders.
|
||||
|
||||
The `ref` attribute can be used to attach the `NodeRef` to an HTML element. In callbacks,
|
||||
you can then get the DOM `Element` that the ref is attached to.
|
||||
|
||||
## Example
|
||||
|
||||
|
||||
@ -4,7 +4,7 @@ title: 'use_reducer'
|
||||
|
||||
`use_reducer` is an alternative to [`use_state`](./use-state). It is used to handle more complex component's state.
|
||||
|
||||
It accepts an initial state function and returns a `UseReducerHandle` that dereferences to the state,
|
||||
It accepts an initializer function and returns a `UseReducerHandle` that dereferences to the state,
|
||||
and a dispatch function.
|
||||
The dispatch function takes one argument of type `Action`. When called, the action and current value
|
||||
are passed to the reducer function which computes a new state that is returned,
|
||||
@ -20,7 +20,7 @@ values from within the hooks.
|
||||
:::
|
||||
|
||||
The state object returned by the initial state function is required to
|
||||
implement a `Reducible` trait which provides an `Action` type and a
|
||||
implement a `Reducible` trait which defines the associated `Action` type and a
|
||||
reducer function.
|
||||
|
||||
This hook will always trigger a re-render upon receiving an action. See
|
||||
|
||||
@ -19,7 +19,7 @@ values from within the hook.
|
||||
|
||||
This hook will always trigger a re-render upon receiving a new state. See
|
||||
[`use_state_eq`](#use_state_eq) if you want the component to only
|
||||
re-render when the state changes.
|
||||
re-render when the new state compares unequal to the existing one.
|
||||
|
||||
## Example
|
||||
|
||||
|
||||
@ -5,10 +5,11 @@ slug: /concepts/function-components
|
||||
|
||||
Lets revisit this previous statement:
|
||||
|
||||
> Yew mostly operates on the idea of keeping everything that a reusable piece of
|
||||
> UI may need, in one place - rust files.
|
||||
> Yew centrally operates on the idea of keeping everything that a reusable piece of
|
||||
> UI may need in one place - rust files.
|
||||
|
||||
It is only partially correct, "rust files" should be replaced with "components".
|
||||
We will refine this statement, by introducing the concept that will define the logic and
|
||||
presentation behaviour of an application: "components".
|
||||
|
||||
## What are Components?
|
||||
|
||||
@ -18,18 +19,21 @@ They:
|
||||
|
||||
- Take arguments in form of [Props](./properties.mdx)
|
||||
- Can have their own state
|
||||
- Get computed into HTML visible to the user (DOM)
|
||||
- Compute pieces of HTML visible to the user (DOM)
|
||||
|
||||
## Two flavours of Yew Components
|
||||
|
||||
You are currently reading about function components - the recommended way to write components when starting with Yew.
|
||||
You are currently reading about function components - the recommended way to write components
|
||||
when starting with Yew and when writing simple presentation logic.
|
||||
|
||||
But we have to note that there is a more advanced, but less recommended way to write them - [Struct components](advanced-topics/struct-components/introduction.mdx)
|
||||
There is a more advanced, but less accessible, way to write components - [Struct components](advanced-topics/struct-components/introduction.mdx).
|
||||
They allow very detailed control, though you will not need that level of detail most of the time.
|
||||
|
||||
## Creating function components
|
||||
|
||||
To create a function component add the `#[function_component]` attribute to a function.
|
||||
Also name the function in PascalCase as it is the convention for naming components.
|
||||
By convention, the function is named in PascalCase, like all components, to contrast its
|
||||
use to normal html elements inside the `html!` macro.
|
||||
|
||||
```rust
|
||||
use yew::{function_component, html, Html};
|
||||
@ -39,31 +43,34 @@ fn HelloWorld() -> Html {
|
||||
html! { "Hello world" }
|
||||
}
|
||||
|
||||
// Then somewhere else you can use the component inside the `html!`
|
||||
// Then somewhere else you can use the component inside `html!`
|
||||
#[function_component]
|
||||
fn App() -> Html {
|
||||
html! {<HelloWorld />}
|
||||
html! { <HelloWorld /> }
|
||||
}
|
||||
```
|
||||
|
||||
## What happens to components
|
||||
|
||||
Yew will build a tree of these components that from the previous example would look like this:
|
||||
When rendering, Yew will build a virtual tree of these components.
|
||||
It will call the view function of each (function) component to compute a virtual version (VDOM) of the DOM
|
||||
that you as the library user see as the `Html` type.
|
||||
For the previous example this would look like this:
|
||||
|
||||
```md
|
||||
<App />
|
||||
|
|
||||
<HelloWorld />
|
||||
```xhtml
|
||||
<App>
|
||||
<HelloWorld>
|
||||
<p>"Hello world"</p>
|
||||
</HelloWord>
|
||||
</App>
|
||||
```
|
||||
|
||||
It will call those functions / function components to compute a virtual version of the DOM (VDOM) that you as the library user see as the `Html` type.
|
||||
|
||||
Yew will compare current DOM with VDOM and only update the new/changed/necessary parts.
|
||||
|
||||
When an update is necessary, Yew will again call the view function and reconcile the new virtual DOM with its
|
||||
previous version and only propagate the new/changed/necessary parts to the actual DOM.
|
||||
This is what we call **rendering**.
|
||||
|
||||
:::note
|
||||
|
||||
Behind the scenes `Html` type is just an alias for `VNode` - virtual node.
|
||||
Behind the scenes `Html` is just an alias for `VNode` - virtual node.
|
||||
|
||||
:::
|
||||
|
||||
@ -3,12 +3,18 @@ title: 'Node Refs'
|
||||
description: 'Out-of-band DOM access'
|
||||
---
|
||||
|
||||
The `ref` keyword can be used inside of any HTML element or component to get the DOM `Element` that
|
||||
the item is attached to. This can be used to make changes to the DOM outside of the `view` lifecycle
|
||||
method.
|
||||
The `ref` attribute can be used to attach the `NodeRef` to an HTML element. In callbacks,
|
||||
you can then get the DOM `Element` that the ref is attached to. This can be used to make
|
||||
changes to the DOM outside of the `view` lifecycle method, retrieve the value of an `<input>`
|
||||
and other direct interactions with the DOM via the javascript API.
|
||||
|
||||
This is useful for getting ahold of canvas elements, or scrolling to different sections of a page.
|
||||
|
||||
:::caution
|
||||
Do not manually modify the DOM tree that is rendered by Yew. Treat the `NodeRef` as a read-only
|
||||
access, if you are unsure.
|
||||
:::
|
||||
|
||||
## Example
|
||||
|
||||
See [use_node_ref hook](./hooks/use-node-ref)
|
||||
|
||||
@ -12,15 +12,14 @@ Properties are often shortened as "Props".
|
||||
|
||||
:::
|
||||
|
||||
Properties are essentially component function arguments that Yew can keep watch on.
|
||||
Components can have an associated properties type which describes what is passed down from the parent.
|
||||
Properties are essentially component arguments that Yew can keep watch on.
|
||||
|
||||
Props are defined using the `Properties` trait.
|
||||
A type has to implement the `Properties` trait before it can be used as the properties of a component.
|
||||
|
||||
## Reactivity
|
||||
|
||||
Yew always checks if props changed to know if the component needs to be rerendered.
|
||||
This way Yew can be considered a very reactive framework as any change from the parent will always be propagated downwards
|
||||
Yew checks if props have changed when reconciling the vdom during rerendering, to know if nested components needs to be rerendered.
|
||||
This way Yew can be considered a very reactive framework as changes from the parent will always be propagated downwards
|
||||
and the view will never be out of sync from the data coming from props/state.
|
||||
|
||||
:::tip
|
||||
@ -29,14 +28,9 @@ If you have not yet completed the [tutorial](../../tutorial), try it out and tes
|
||||
|
||||
:::
|
||||
|
||||
## Memory/speed overhead of using Properties
|
||||
|
||||
Internally properties are reference counted. This means that only a pointer is passed down the component tree for props.
|
||||
It saves us from the cost of having to clone the entire props, which might be expensive.
|
||||
|
||||
## Derive macro
|
||||
|
||||
Yew provides a derive macro to easily implement the `Properties` trait.
|
||||
Yew provides a derive macro to easily implement the `Properties` trait on structs.
|
||||
|
||||
Types for which you derive `Properties` must also implement `PartialEq` so Yew can do data comparison.
|
||||
|
||||
@ -51,7 +45,8 @@ pub struct Props {
|
||||
|
||||
## Use in function components
|
||||
|
||||
The attribute `#[function_component]` allows to optionally specify Props in the function arguments
|
||||
The attribute `#[function_component]` allows to optionally receive Props in the function arguments. To supply them,
|
||||
they are assigned via attributes in the `html!` macro.
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="with-props" label="With Props">
|
||||
@ -106,8 +101,8 @@ fn App() -> Html {
|
||||
|
||||
## Derive macro field attributes
|
||||
|
||||
When deriving `Properties`, all fields are required by default.
|
||||
The following attributes allow you to give your props initial values which will be used when parent has not set them.
|
||||
When deriving `Properties` all fields are required by default.
|
||||
The following attributes allow you to give your props default values which will be used when parent has not set them.
|
||||
|
||||
:::tip
|
||||
Attributes aren't visible in Rustdoc generated documentation.
|
||||
@ -155,7 +150,8 @@ fn Case2() -> Html {
|
||||
<TabItem value="prop_or_value" label="#[prop_or(value)]">
|
||||
|
||||
Use `value` to initialize the prop value. `value` can be any expression that returns the field's type.
|
||||
For example, to default a boolean prop to `true`, use the attribute `#[prop_or(true)]`.
|
||||
For example, to default a boolean prop to `true`, use the attribute `#[prop_or(true)]`. The expression
|
||||
is evaluated when the properties are constructed and no explicit value has been given.
|
||||
|
||||
```rust
|
||||
use yew::{function_component, html, Html, Properties};
|
||||
@ -189,6 +185,7 @@ fn Case2() -> Html {
|
||||
<TabItem value="prop_or_else_function" label="#[prop_or_else(function)]">
|
||||
|
||||
Call `function` to initialize the prop value. `function` should have the signature `FnMut() -> T` where `T` is the field type.
|
||||
The function is called when no explicit value has been given for that attribute.
|
||||
|
||||
```rust
|
||||
use yew::{function_component, html, Html, Properties};
|
||||
@ -225,6 +222,11 @@ fn Case2() -> Html {
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Memory/speed overhead of using Properties
|
||||
|
||||
Internally properties are reference counted. This means that only a shared pointer is passed down the component tree for props.
|
||||
It saves us from the cost of having to clone the entire props, which might be expensive.
|
||||
|
||||
## Props macro
|
||||
|
||||
The `yew::props!` macro allows you to build properties the same way the `html!` macro does it.
|
||||
|
||||
@ -2,15 +2,12 @@
|
||||
title: 'Pure Components'
|
||||
---
|
||||
|
||||
## Pure function definition
|
||||
A function component is considered [pure] when the returned `Html` is deterministically derived
|
||||
from its props, and its view function mutates no state or has other side-effects.
|
||||
|
||||
A function is considered pure when the return values are deterministic given the same parameters, and it has no side-effects.
|
||||
[pure]: https://en.wikipedia.org/wiki/Pure_function
|
||||
|
||||
## Pure components
|
||||
|
||||
In the same sense component is pure when it does not have any state or side_effects and with the given props always returns the same `Html`.
|
||||
|
||||
For example below is a pure component, for a given prop `is_loading` it will always result in same `Html` without any side effects.
|
||||
For example below is a pure component. For a given prop `is_loading` it will always result in the same `Html` without any side effects.
|
||||
|
||||
```rust
|
||||
use yew::{Properties, function_component, Html, html};
|
||||
@ -22,7 +19,7 @@ pub struct Props {
|
||||
|
||||
#[function_component]
|
||||
fn HelloWorld(props: &Props) -> Html {
|
||||
if props.is_loading.clone() {
|
||||
if props.is_loading {
|
||||
html! { "Loading" }
|
||||
} else {
|
||||
html! { "Hello world" }
|
||||
@ -30,7 +27,13 @@ fn HelloWorld(props: &Props) -> Html {
|
||||
}
|
||||
```
|
||||
|
||||
## Un-pure components
|
||||
:::note
|
||||
If you have an internal pure component that makes no use of hooks and other component machinery, you can often write it instead
|
||||
as a normal function returning `Html` and avoid a bit of overhead for Yew, related to running the component lifecycle. Use
|
||||
[expression syntax](concepts/html/literals-and-expressions.mdx#expressions) to render them in `html!`.
|
||||
:::
|
||||
|
||||
Though you probably wonder how can a component even be un-pure if its just a function that is called every render and if it does not use any globals.
|
||||
## Impure components
|
||||
|
||||
You might wonder if a component can be impure if it does not use any globals, since its just a function that is called every render.
|
||||
This is where the next topic comes in - [hooks](./hooks)
|
||||
|
||||
@ -6,13 +6,13 @@ title: 'State'
|
||||
|
||||
This table can be used as a guide when deciding what state storing type fits best for your use case:
|
||||
|
||||
| Type | Rerender when? | Scope |
|
||||
| ---------------------------------------------------- | ---------------------------- | ------------------- |
|
||||
| [use_state](./hooks/use-state) | got set | component instance |
|
||||
| [use_state_eq](./hooks/use-state#use_state_eq) | got set with diff. value | component instance |
|
||||
| [use_reducer](./hooks/use-reducer) | got reduced | component instance |
|
||||
| [use_reducer_eq](./hooks/use-reducer#use_reducer_eq) | got reduced with diff. value | component instance |
|
||||
| [use_memo](./hooks/use-memo) | dependencies changed | component instance |
|
||||
| [use_callback](./hooks/use-callback) | dependencies changed | component instance |
|
||||
| [use_mut_ref](./hooks/use-mut-ref) | - | component instance |
|
||||
| a static global variable | - | global, used by all |
|
||||
| Hook | Type | Rerender when? | Scope |
|
||||
| ---------------------------------------------------- | -------------------------- | ---------------------------- | ------------------- |
|
||||
| [use_state](./hooks/use-state) | `T` | got set | component instance |
|
||||
| [use_state_eq](./hooks/use-state#use_state_eq) | `T: PartialEq` | got set with diff. value | component instance |
|
||||
| [use_reducer](./hooks/use-reducer) | `T: Reducible` | got reduced | component instance |
|
||||
| [use_reducer_eq](./hooks/use-reducer#use_reducer_eq) | `T: Reducible + PartialEq` | got reduced with diff. value | component instance |
|
||||
| [use_memo](./hooks/use-memo) | `Deps -> T` | dependencies changed | component instance |
|
||||
| [use_callback](./hooks/use-callback) | `Deps -> Callback<E>` | dependencies changed | component instance |
|
||||
| [use_mut_ref](./hooks/use-mut-ref) | `T` | - | component instance |
|
||||
| a static global variable | `T` | - | global, used by all |
|
||||
|
||||
@ -50,18 +50,17 @@ html! {
|
||||
|
||||
## Keyed lists
|
||||
|
||||
A keyed list is a optimized list that has keys on all tags.
|
||||
`key` is a special prop provided by Yew which gives an html element a unique identifier which can be used for optimization purposes.
|
||||
A keyed list is an optimized list that has keys on **all** children.
|
||||
`key` is a special prop provided by Yew which gives an html element or component a unique identifier
|
||||
which is used for optimization purposes inside Yew.
|
||||
|
||||
:::caution
|
||||
|
||||
Key has to be unique and must not depend on the order of the list.
|
||||
|
||||
Key has to be unique only in each list, in constrast to the global uniqueness of html `id`s. It must not depend on the order of the list.
|
||||
:::
|
||||
|
||||
It is always recommended to add keys to lists.
|
||||
|
||||
Keys can be added by passing a unique value to the special `key` prop:
|
||||
Keys can be added by passing a unique `String`, `str` or integer to the special `key` prop:
|
||||
|
||||
```rust , ignore
|
||||
use yew::prelude::*;
|
||||
@ -82,7 +81,7 @@ html! {
|
||||
|
||||
### Performance increases
|
||||
|
||||
We have [Keyed list](https://github.com/yewstack/yew/tree/master/examples/keyed_list) example that lets you test the performance improvements, but here is rough example of testing:
|
||||
We have [Keyed list](https://github.com/yewstack/yew/tree/master/examples/keyed_list) example that lets you test the performance improvements, but here is rough rundown:
|
||||
|
||||
1. Go to [Keyed list](https://github.com/yewstack/yew/tree/master/examples/keyed_list) hosted demo
|
||||
2. Add 500 elements.
|
||||
@ -98,7 +97,9 @@ So just at the time of writing this, for 500 components its a x2 increase of spe
|
||||
### Detailed explanation
|
||||
|
||||
Usually you just need a key on every list item when you iterate and the order of data can change.
|
||||
So lets say you iterate through `["bob","sam","rob"]` ended up with html:
|
||||
It's used to speed up the reconciliation process when re-rendering the list.
|
||||
|
||||
Without keys, lets assume you iterate through `["bob","sam","rob"]`, ending up with the html:
|
||||
|
||||
```html
|
||||
<div id="bob">My name is Bob</div>
|
||||
@ -106,12 +107,12 @@ So lets say you iterate through `["bob","sam","rob"]` ended up with html:
|
||||
<div id="rob">My name is rob</div>
|
||||
```
|
||||
|
||||
Then if your list changed to `["bob","rob"]`,
|
||||
yew would delete from previous html element with id="rob" and update id="sam" to be id="rob"
|
||||
Then on the next render, if your list changed to `["bob","rob"]`, yew could delete
|
||||
the element with id="rob" and update id="sam" to be id="rob"
|
||||
|
||||
Now if you had added a key to each element, html would stay the same, but in case where it changed to `["bob","rob"]`, yew would just delete the second html element since it knows which one it is.
|
||||
|
||||
Keys also help for weird cases where yew reuses html elements.
|
||||
If you had added a key to each element, the initial html would be the same, but after
|
||||
the render with the modified list, `["bob","rob"]`, yew would just delete the second
|
||||
html element and leave the rest untouched since it can use the keys to associate them.
|
||||
|
||||
If you ever encounter a bug/"feature" where you switch from one component to another but both have a div as the highest rendered element.
|
||||
Yew reuses the rendered html div in those cases as an optimization.
|
||||
|
||||
@ -2,9 +2,10 @@
|
||||
title: 'Build a sample app'
|
||||
---
|
||||
|
||||
## Using a starter template
|
||||
Once you have the environment ready, you can either choose to use a starter template that contains
|
||||
the boilerplate needed for a basic Yew app or manually set up a small project.
|
||||
|
||||
Once you have the environment ready, you can use the starter template to create the boilerplate needed for a basic Yew app.
|
||||
## Using a starter template
|
||||
|
||||
Install [`cargo-generate`](https://github.com/cargo-generate/cargo-generate) by following their installation instructions
|
||||
then run the following command:
|
||||
|
||||
@ -14,19 +14,36 @@ Using a different editor? Feel free to add instructions for your editor of choic
|
||||
1. Navigate to File | Settings | Editor | Live Templates.
|
||||
2. Select Rust and click on the + icon to add a new Live Template.
|
||||
3. Give it a name and description of your preference.
|
||||
4. Paste the following snippet in Template Text section.
|
||||
4. Paste the following snippet(s) into the Template Text section.
|
||||
5. Change the applicability on the lower right, select Rust > Item > Module
|
||||
|
||||
```rust ,ignore
|
||||
use yew::prelude::*;
|
||||
For function components, use the following template.
|
||||
|
||||
- (Optional) Click on Edit Variable and give `tag` a reasonable default value like "div", with double quotes.
|
||||
|
||||
```rust ,ignore
|
||||
#[derive(PartialEq, Properties)]
|
||||
pub struct $Name$Props {
|
||||
}
|
||||
|
||||
#[function_component]
|
||||
pub fn $Name$(props: &$Name$Props) -> Html {
|
||||
html! {
|
||||
<$tag$>$END$</$tag$>
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
For struct components, you can use the following more complicated template.
|
||||
|
||||
```rust ,ignore
|
||||
struct $NAME$;
|
||||
|
||||
enum Msg {
|
||||
enum $NAME$Msg {
|
||||
}
|
||||
|
||||
impl Component for $NAME$ {
|
||||
type Message = Msg;
|
||||
type Message = $NAME$Msg;
|
||||
type Properties = ();
|
||||
|
||||
fn create(ctx: &Context<Self>) -> Self {
|
||||
@ -41,28 +58,6 @@ impl Component for $NAME$ {
|
||||
}
|
||||
```
|
||||
|
||||
For function components, use the template below. Additionally:
|
||||
|
||||
1. Click on Edit Variable
|
||||
2. In the `func_name` row, set the Expression column to `snakeCase(NAME)` so that `ComponentName` will be automatically
|
||||
filled as `component_name`
|
||||
in the function definition.
|
||||
3. In the `func_name` row, check "skip if defined" so this autogenerated field won't be navigated to.
|
||||
4. (Optional) give `tag` a reasonable default value like "div", with double quotes.
|
||||
|
||||
```rust ,ignore
|
||||
#[derive(Properties, PartialEq, Clone)]
|
||||
pub struct $Name$Props {
|
||||
}
|
||||
|
||||
#[function_component($Name$)]
|
||||
pub fn $func_name$(props: &$Name$Props) -> Html {
|
||||
html! {
|
||||
<$tag$>$END$</$tag$>
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### VS Code
|
||||
|
||||
1. Navigate to File > Preferences > User Snippets.
|
||||
@ -71,18 +66,32 @@ pub fn $func_name$(props: &$Name$Props) -> Html {
|
||||
|
||||
```json
|
||||
{
|
||||
"Create new Yew component": {
|
||||
"prefix": "YOUR PREFIX OF CHOICE",
|
||||
"New Yew function component": {
|
||||
"prefix": "yewfc",
|
||||
"body": [
|
||||
"use yew::prelude::*;",
|
||||
"#[derive(PartialEq, Properties)]",
|
||||
"pub struct ${1:ComponentName}Props {}",
|
||||
"",
|
||||
"pub struct ${1};",
|
||||
"#[function_component]",
|
||||
"pub fn $1(props: &${1}Props) -> Html {",
|
||||
" let ${1}Props {} = props;",
|
||||
" html! {",
|
||||
" <${2:div}>$0</${2}>",
|
||||
" }",
|
||||
"}"
|
||||
],
|
||||
"description": "Create a minimal Yew function component"
|
||||
},
|
||||
"New Yew struct component": {
|
||||
"prefix": "yewsc",
|
||||
"body": [
|
||||
"pub struct ${1:ComponentName};",
|
||||
"",
|
||||
"pub enum Msg {",
|
||||
"pub enum ${1}Msg {",
|
||||
"}",
|
||||
"",
|
||||
"impl Component for ${1} {",
|
||||
" type Message = Msg;",
|
||||
" type Message = ${1}Msg;",
|
||||
" type Properties = ();",
|
||||
"",
|
||||
" fn create(ctx: &Context<Self>) -> Self {",
|
||||
@ -91,7 +100,7 @@ pub fn $func_name$(props: &$Name$Props) -> Html {
|
||||
"",
|
||||
" fn view(&self, ctx: &Context<Self>) -> Html {",
|
||||
" html! {",
|
||||
" ${0}",
|
||||
" $0",
|
||||
" }",
|
||||
" }",
|
||||
"}"
|
||||
|
||||
@ -2,10 +2,15 @@
|
||||
title: 'Examples'
|
||||
---
|
||||
|
||||
The Yew repository is contains many [examples] (in various states of maintenance).
|
||||
The Yew repository contains many [examples] (in various states of maintenance).
|
||||
We recommend perusing them to get a feel for how to use different features of the framework.
|
||||
We also welcome Pull Requests and issues for when they inevitably get neglected and need some ♥️
|
||||
|
||||
For more details including a list of examples, refer to the [README][examples].
|
||||
|
||||
::: note
|
||||
Most of the examples have a live deployment that can be found at https://examples.yew.rs/<example_name>.
|
||||
Click the shield on their individual README page in their respective sub-folder to navigate to the live demo.
|
||||
:::
|
||||
|
||||
[examples]: https://github.com/yewstack/yew/tree/master/examples
|
||||
|
||||
@ -23,9 +23,9 @@
|
||||
"message": "HTML",
|
||||
"description": "The label for category HTML in sidebar docs"
|
||||
},
|
||||
"sidebar.docs.category.Function Components": {
|
||||
"sidebar.docs.category.Components": {
|
||||
"message": "Function Components",
|
||||
"description": "The label for category Function Components in sidebar docs"
|
||||
"description": "The label for category Components in sidebar docs"
|
||||
},
|
||||
"sidebar.docs.category.Advanced topics": {
|
||||
"message": "Advanced topics",
|
||||
@ -63,34 +63,22 @@
|
||||
"message": "yew-router",
|
||||
"description": "The label for category yew-router in sidebar docs"
|
||||
},
|
||||
"sidebar.docs.category.Intro With Basic Web Technologies": {
|
||||
"sidebar.docs.category.Using Basic Web Technologies In Yew": {
|
||||
"message": "Intro With Basic Web Technologies",
|
||||
"description": "The label for category Intro With Basic Web Technologies in sidebar docs"
|
||||
"description": "The label for category Using Basic Web Technologies In Yew in sidebar docs"
|
||||
},
|
||||
"sidebar.docs.category.Intro With Basic Web Technologies.link.generated-index.title": {
|
||||
"sidebar.docs.category.Using Basic Web Technologies In Yew.link.generated-index.title": {
|
||||
"message": "Yew Take on Basic Web Technologies",
|
||||
"description": "The generated-index page title for category Intro With Basic Web Technologies in sidebar docs"
|
||||
"description": "The generated-index page title for category Using Basic Web Technologies In Yew in sidebar docs"
|
||||
},
|
||||
"sidebar.docs.category.Intro With Basic Web Technologies.link.generated-index.description": {
|
||||
"sidebar.docs.category.Using Basic Web Technologies In Yew.link.generated-index.description": {
|
||||
"message": "Yew mostly operates on the idea of keeping everything that a reusable piece of UI may need, in one place - rust files. But also seeks to stay close to the original look of the technology. Explore further to fully grasp what we mean by these statements:",
|
||||
"description": "The generated-index page description for category Intro With Basic Web Technologies in sidebar docs"
|
||||
"description": "The generated-index page description for category Using Basic Web Technologies In Yew in sidebar docs"
|
||||
},
|
||||
"sidebar.docs.category.Hooks": {
|
||||
"message": "Hooks",
|
||||
"description": "The label for category Hooks in sidebar docs"
|
||||
},
|
||||
"sidebar.docs.category.Javascript with Rust": {
|
||||
"message": "Javascript with Rust",
|
||||
"description": "The label for category Javascript with Rust in sidebar docs"
|
||||
},
|
||||
"sidebar.docs.category.Javascript with Rust.link.generated-index.title": {
|
||||
"message": "wasm-bindgen",
|
||||
"description": "The generated-index page title for category Javascript with Rust in sidebar docs"
|
||||
},
|
||||
"sidebar.docs.category.Javascript with Rust.link.generated-index.description": {
|
||||
"message": "Learn about wasm-bindgen",
|
||||
"description": "The generated-index page description for category Javascript with Rust in sidebar docs"
|
||||
},
|
||||
"sidebar.docs.category.Struct Components": {
|
||||
"message": "Struct Components",
|
||||
"description": "The label for category Struct Components in sidebar docs"
|
||||
|
||||
@ -23,9 +23,9 @@
|
||||
"message": "HTML",
|
||||
"description": "The label for category HTML in sidebar docs"
|
||||
},
|
||||
"sidebar.docs.category.Function Components": {
|
||||
"sidebar.docs.category.Components": {
|
||||
"message": "Function Components",
|
||||
"description": "The label for category Function Components in sidebar docs"
|
||||
"description": "The label for category Components in sidebar docs"
|
||||
},
|
||||
"sidebar.docs.category.Advanced topics": {
|
||||
"message": "高级主题",
|
||||
@ -63,34 +63,22 @@
|
||||
"message": "yew-router",
|
||||
"description": "The label for category yew-router in sidebar docs"
|
||||
},
|
||||
"sidebar.docs.category.Intro With Basic Web Technologies": {
|
||||
"sidebar.docs.category.Using Basic Web Technologies In Yew": {
|
||||
"message": "Intro With Basic Web Technologies",
|
||||
"description": "The label for category Intro With Basic Web Technologies in sidebar docs"
|
||||
"description": "The label for category Using Basic Web Technologies In Yew in sidebar docs"
|
||||
},
|
||||
"sidebar.docs.category.Intro With Basic Web Technologies.link.generated-index.title": {
|
||||
"sidebar.docs.category.Using Basic Web Technologies In Yew.link.generated-index.title": {
|
||||
"message": "Yew Take on Basic Web Technologies",
|
||||
"description": "The generated-index page title for category Intro With Basic Web Technologies in sidebar docs"
|
||||
"description": "The generated-index page title for category Using Basic Web Technologies In Yew in sidebar docs"
|
||||
},
|
||||
"sidebar.docs.category.Intro With Basic Web Technologies.link.generated-index.description": {
|
||||
"sidebar.docs.category.Using Basic Web Technologies In Yew.link.generated-index.description": {
|
||||
"message": "Yew mostly operates on the idea of keeping everything that a reusable piece of UI may need, in one place - rust files. But also seeks to stay close to the original look of the technology. Explore further to fully grasp what we mean by these statements:",
|
||||
"description": "The generated-index page description for category Intro With Basic Web Technologies in sidebar docs"
|
||||
"description": "The generated-index page description for category Using Basic Web Technologies In Yew in sidebar docs"
|
||||
},
|
||||
"sidebar.docs.category.Hooks": {
|
||||
"message": "Hooks",
|
||||
"description": "The label for category Hooks in sidebar docs"
|
||||
},
|
||||
"sidebar.docs.category.Javascript with Rust": {
|
||||
"message": "Javascript with Rust",
|
||||
"description": "The label for category Javascript with Rust in sidebar docs"
|
||||
},
|
||||
"sidebar.docs.category.Javascript with Rust.link.generated-index.title": {
|
||||
"message": "wasm-bindgen",
|
||||
"description": "The generated-index page title for category Javascript with Rust in sidebar docs"
|
||||
},
|
||||
"sidebar.docs.category.Javascript with Rust.link.generated-index.description": {
|
||||
"message": "Learn about wasm-bindgen",
|
||||
"description": "The generated-index page description for category Javascript with Rust in sidebar docs"
|
||||
},
|
||||
"sidebar.docs.category.Struct Components": {
|
||||
"message": "Struct Components",
|
||||
"description": "The label for category Struct Components in sidebar docs"
|
||||
|
||||
@ -23,9 +23,9 @@
|
||||
"message": "HTML",
|
||||
"description": "The label for category HTML in sidebar docs"
|
||||
},
|
||||
"sidebar.docs.category.Function Components": {
|
||||
"sidebar.docs.category.Components": {
|
||||
"message": "Function Components",
|
||||
"description": "The label for category Function Components in sidebar docs"
|
||||
"description": "The label for category Components in sidebar docs"
|
||||
},
|
||||
"sidebar.docs.category.Advanced topics": {
|
||||
"message": "進階主題",
|
||||
@ -63,34 +63,22 @@
|
||||
"message": "yew-router",
|
||||
"description": "The label for category yew-router in sidebar docs"
|
||||
},
|
||||
"sidebar.docs.category.Intro With Basic Web Technologies": {
|
||||
"sidebar.docs.category.Using Basic Web Technologies In Yew": {
|
||||
"message": "Intro With Basic Web Technologies",
|
||||
"description": "The label for category Intro With Basic Web Technologies in sidebar docs"
|
||||
"description": "The label for category Using Basic Web Technologies In Yew in sidebar docs"
|
||||
},
|
||||
"sidebar.docs.category.Intro With Basic Web Technologies.link.generated-index.title": {
|
||||
"sidebar.docs.category.Using Basic Web Technologies In Yew.link.generated-index.title": {
|
||||
"message": "Yew Take on Basic Web Technologies",
|
||||
"description": "The generated-index page title for category Intro With Basic Web Technologies in sidebar docs"
|
||||
"description": "The generated-index page title for category Using Basic Web Technologies In Yew in sidebar docs"
|
||||
},
|
||||
"sidebar.docs.category.Intro With Basic Web Technologies.link.generated-index.description": {
|
||||
"sidebar.docs.category.Using Basic Web Technologies In Yew.link.generated-index.description": {
|
||||
"message": "Yew mostly operates on the idea of keeping everything that a reusable piece of UI may need, in one place - rust files. But also seeks to stay close to the original look of the technology. Explore further to fully grasp what we mean by these statements:",
|
||||
"description": "The generated-index page description for category Intro With Basic Web Technologies in sidebar docs"
|
||||
"description": "The generated-index page description for category Using Basic Web Technologies In Yew in sidebar docs"
|
||||
},
|
||||
"sidebar.docs.category.Hooks": {
|
||||
"message": "Hooks",
|
||||
"description": "The label for category Hooks in sidebar docs"
|
||||
},
|
||||
"sidebar.docs.category.Javascript with Rust": {
|
||||
"message": "Javascript with Rust",
|
||||
"description": "The label for category Javascript with Rust in sidebar docs"
|
||||
},
|
||||
"sidebar.docs.category.Javascript with Rust.link.generated-index.title": {
|
||||
"message": "wasm-bindgen",
|
||||
"description": "The generated-index page title for category Javascript with Rust in sidebar docs"
|
||||
},
|
||||
"sidebar.docs.category.Javascript with Rust.link.generated-index.description": {
|
||||
"message": "Learn about wasm-bindgen",
|
||||
"description": "The generated-index page description for category Javascript with Rust in sidebar docs"
|
||||
},
|
||||
"sidebar.docs.category.Struct Components": {
|
||||
"message": "Struct Components",
|
||||
"description": "The label for category Struct Components in sidebar docs"
|
||||
|
||||
@ -30,22 +30,26 @@ module.exports = {
|
||||
items: [
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Intro With Basic Web Technologies',
|
||||
label: 'Using Basic Web Technologies In Yew',
|
||||
link: {
|
||||
type: 'generated-index',
|
||||
title: 'Yew Take on Basic Web Technologies',
|
||||
title: "Yew's Take on Basic Web Technologies",
|
||||
description:
|
||||
'Yew mostly operates on the idea of keeping everything that a reusable piece of UI may need, in one place - rust files. But also seeks to stay close to the original look of the technology. Explore further to fully grasp what we mean by these statements:',
|
||||
'Yew centrally operates on the idea of keeping everything that a reusable piece of UI may need' +
|
||||
'in one place - rust files, while also keeping the underlying technology accessible where necessary. ' +
|
||||
'Explore further to fully grasp what we mean by these statements:',
|
||||
},
|
||||
items: [
|
||||
'concepts/basic-web-technologies/html',
|
||||
'concepts/basic-web-technologies/css',
|
||||
'concepts/basic-web-technologies/js',
|
||||
'concepts/basic-web-technologies/wasm-bindgen',
|
||||
'concepts/basic-web-technologies/web-sys',
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Function Components',
|
||||
label: 'Components',
|
||||
link: {
|
||||
type: 'doc',
|
||||
id: 'concepts/function-components/introduction',
|
||||
@ -71,6 +75,7 @@ module.exports = {
|
||||
'concepts/function-components/hooks/use-memo',
|
||||
'concepts/function-components/hooks/use-callback',
|
||||
'concepts/function-components/hooks/use-context',
|
||||
'concepts/function-components/hooks/use-force-update',
|
||||
'concepts/function-components/hooks/custom-hooks',
|
||||
],
|
||||
},
|
||||
@ -95,20 +100,6 @@ module.exports = {
|
||||
'concepts/html/conditional-rendering',
|
||||
],
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Javascript with Rust',
|
||||
link: {
|
||||
type: 'generated-index',
|
||||
title: 'wasm-bindgen',
|
||||
description: 'Learn about wasm-bindgen',
|
||||
slug: '/concepts/wasm-bindgen',
|
||||
},
|
||||
items: [
|
||||
'concepts/wasm-bindgen/introduction',
|
||||
'concepts/wasm-bindgen/web-sys',
|
||||
],
|
||||
},
|
||||
'concepts/agents',
|
||||
'concepts/contexts',
|
||||
'concepts/router',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user