Yew Tutorial (v0.19) - part 1
Before Yew tutorial
I want to try with wasm-pack, but after several tries, I realized that it was a bad try.
And most parts of the official document uses Trunk, so I was back to Trunk.
Please refer to my post about Trunk.
Versions
- Cargo: 1.65
- Yew: 0.19
Set up Rust environment for Yew
rustup target add wasm32-unknown-unknown
cargo install trunk
My summary on Yew tutorial page
I followed the official “Video page” tutorial.
Basic ideas
- Yew injects
bodyelement by default. You can change which part to be injected. - In Yew world, you will create a lot of components. They are literally components of an app in Yew world.
- You can create component by adding an attribute to function, like
#[function_component(NameComponent)]. - Or,
impl Component for NameComponent. Function components are recommended by official, but we will see thisimplway in the next part). - You can launch your app (the entry component) by
yew::start_app::<NameComponent>();.- https://docs.rs/yew/latest/yew/fn.start_app.html
- By definition, this function inject
bodyelement.
html!macro enable to write JSX-like syntax.- Expressions must be wrapped in curly braces (
{ }). - There must only be one root node. If you want to have multiple elements without wrapping them in a container, an empty tag/fragment (
<> ... </>) is used.
- Expressions must be wrapped in curly braces (
- In Yew world, there are two types of components. function component, and struct component.
- Actually,
yew::start_app::<NameComponent>();run the function componentNameComponent.
- Actually,
- You can define struct component by adding attribute
#[derive(Properties)]to struct. Struct components are data, used by input of function components. - A function component takes only one property argument.
- If function returns
Htmltype, for example, you can use a function component like this:// in html! macro <MyPropStruct field1={my_struct.clone()} /> - Properties are used to pass data down from a parent component to a child component. Changin property could make your Yew app interactive (non-static).
Change HTML page
- Page actions can be defined by
Callbackenum. - There are only two components in Yew world, so every action is kicked by Components.
- For example, to change the view, struct component need to notify its “parent” component the change (passing handlers).
- Callback functions could be used with the
onclickattribute:html! { <p onclick={my_callback}> {format!("{}: {}", video.speaker, video.title)} </p> }
Hook
Hooks are functions that let you “hook into” components’ state and/or lifecycle and perform actions.
use_state
- https://docs.rs/yew/latest/yew/functional/fn.use_state.html
- This hook is used to manage state in a function component.
- The “state” is related with lifecycle. Understand lifecycle first.
- It returns
yew::functional::UseStateHandle. setmethod set a value to handler.
How to use callback
Include a callback function in a Struct property (the type is
Callback<T>).#[derive(Properties, PartialEq)] struct VideosListProps { videos: Vec<Video>, on_click: Callback<Video> }Create a (callback) function component which takes the struct property as a parameter.
#[function_component(VideosList)] fn videos_list(VideosListProps { videos, on_click }: &VideosListProps) -> HtmlSet the callback function. In the function component,
emitmethod calls the callback function. (More precisely,emitmethod send aMessageenum to the component.)let on_video_select = { let on_click = on_click.clone(); let video = video.clone(); Callback::from(move |_| { on_click.emit(video.clone()) }) };You can set the callback function in HTML by
onclick={callback_function}html! { <p onclick={on_video_select}>{format!("{}: {}", video.speaker, video.title)}</p> }Use the callback in other components:
// Set a hook let selected_video = use_state(|| None); // Set a callback function let on_video_select = { let selected_video = selected_video.clone(); Callback::from(move |video: Video| { selected_video.set(Some(video)) }) }; // --snip-- html! { <> <h1>{ "RustConf Explorer" }</h1> <div> <h3>{"Videos to watch"}</h3> <VideosList videos={(*videos).clone()} on_click={on_video_select.clone()} /> </div> { for details } </> }
Other take-aways
Fetch external resource from WASM
use reqwasm::http::Request;
Avoid CORS error during local development
trunk serve --proxy-backend=https://yew.rs/tutorial
Terminologies
The terminologies in Yew are quite similar to that of React.
Here is a quote from official README.
Developers who have experience using JSX in React should feel quite at home when using Yew.
For example, the concept of states, components, props are totally similar to React’s.