Skip to content

Commit f50c8c3

Browse files
ranilemc1098
and
mc1098
authored
Components v2 (2) (yewstack#1961)
* Start rewrite * Rc > cloning props * fmt + rm useless file * move props inside `Context` * router compiles * fix boids example * fix counter example * fix crm example * fix dyn_create_destroy_apps example * fix file_upload example * fix futures example * fix game_of_life example * fix inner_html example * fix js_callback example * fix mount_point example * fix keyed_list example * fix web_gl example * fix two_apps example * fix todomvc example * fix timer example * fix store example * fix nested_list example * fix node_refs example * fix pub_sub example * fix multi_thread example * don't call `changed` if props weren't changed * formatting * fix doc tests, remove neq_assign * update router example, fix neq_assign compile errors * fix macro/rest of doc tests * start updating documentation * `Component`'s documentation * Apply suggestions from code review Co-authored-by: mc1098 <m.cripps1@uni.brighton.ac.uk> * Apply suggestions from code review (part 2) * Apply suggestions from code review (part 3) * fix context * clippy * post merge fixes Co-authored-by: mc1098 <m.cripps1@uni.brighton.ac.uk>
1 parent f574c2f commit f50c8c3

File tree

92 files changed

+1063
-1787
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

92 files changed

+1063
-1787
lines changed

examples/boids/src/main.rs

+10-16
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use settings::Settings;
22
use simulation::Simulation;
33
use slider::Slider;
4-
use yew::{html, Component, ComponentLink, Html, ShouldRender};
4+
use yew::html::Scope;
5+
use yew::{html, Component, Context, Html, ShouldRender};
56

67
mod boid;
78
mod math;
@@ -17,7 +18,6 @@ pub enum Msg {
1718
}
1819

1920
pub struct Model {
20-
link: ComponentLink<Self>,
2121
settings: Settings,
2222
generation: usize,
2323
paused: bool,
@@ -26,16 +26,15 @@ impl Component for Model {
2626
type Message = Msg;
2727
type Properties = ();
2828

29-
fn create(_props: Self::Properties, link: ComponentLink<Self>) -> Self {
29+
fn create(_ctx: &Context<Self>) -> Self {
3030
Self {
31-
link,
3231
settings: Settings::load(),
3332
generation: 0,
3433
paused: false,
3534
}
3635
}
3736

38-
fn update(&mut self, msg: Self::Message) -> ShouldRender {
37+
fn update(&mut self, _ctx: &Context<Self>, msg: Msg) -> ShouldRender {
3938
match msg {
4039
Msg::ChangeSettings(settings) => {
4140
self.settings = settings;
@@ -58,11 +57,7 @@ impl Component for Model {
5857
}
5958
}
6059

61-
fn change(&mut self, _props: Self::Properties) -> ShouldRender {
62-
false
63-
}
64-
65-
fn view(&self) -> Html {
60+
fn view(&self, ctx: &Context<Self>) -> Html {
6661
let Self {
6762
ref settings,
6863
generation,
@@ -74,18 +69,17 @@ impl Component for Model {
7469
<>
7570
<h1 class="title">{ "Boids" }</h1>
7671
<Simulation settings={settings.clone()} {generation} {paused} />
77-
{ self.view_panel() }
72+
{ self.view_panel(ctx.link()) }
7873
</>
7974
}
8075
}
8176
}
8277
impl Model {
83-
fn view_panel(&self) -> Html {
84-
let link = &self.link;
78+
fn view_panel(&self, link: &Scope<Self>) -> Html {
8579
let pause_text = if self.paused { "Resume" } else { "Pause" };
8680
html! {
8781
<div class="panel">
88-
{ self.view_settings() }
82+
{ self.view_settings(link) }
8983
<div class="panel__buttons">
9084
<button onclick={link.callback(|_| Msg::TogglePause)}>{ pause_text }</button>
9185
<button onclick={link.callback(|_| Msg::ResetSettings)}>{ "Use Defaults" }</button>
@@ -95,8 +89,8 @@ impl Model {
9589
}
9690
}
9791

98-
fn view_settings(&self) -> Html {
99-
let Self { link, settings, .. } = self;
92+
fn view_settings(&self, link: &Scope<Self>) -> Html {
93+
let Self { settings, .. } = self;
10094

10195
// This helper macro creates a callback which applies the new value to the current settings and sends `Msg::ChangeSettings`.
10296
// Thanks to this, we don't need to have "ChangeBoids", "ChangeCohesion", etc. messages,

examples/boids/src/simulation.rs

+22-39
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ use crate::boid::Boid;
22
use crate::math::Vector2D;
33
use crate::settings::Settings;
44
use gloo::timers::callback::Interval;
5-
use yew::{html, Component, ComponentLink, Html, Properties, ShouldRender};
5+
use yew::{html, Component, Context, Html, Properties, ShouldRender};
66

77
pub const SIZE: Vector2D = Vector2D::new(1600.0, 1000.0);
88

@@ -22,44 +22,37 @@ pub struct Props {
2222

2323
#[derive(Debug)]
2424
pub struct Simulation {
25-
props: Props,
26-
link: ComponentLink<Self>,
2725
boids: Vec<Boid>,
2826
interval: Interval,
2927
}
3028
impl Component for Simulation {
3129
type Message = Msg;
3230
type Properties = Props;
3331

34-
fn create(props: Self::Properties, link: ComponentLink<Self>) -> Self {
35-
let settings = &props.settings;
32+
fn create(ctx: &Context<Self>) -> Self {
33+
let settings = &ctx.props().settings;
3634
let boids = (0..settings.boids)
3735
.map(|_| Boid::new_random(settings))
3836
.collect();
3937

4038
let interval = {
41-
let link = link.clone();
39+
let link = ctx.link().clone();
4240
Interval::new(settings.tick_interval_ms as u32, move || {
4341
link.send_message(Msg::Tick)
4442
})
4543
};
4644

47-
Self {
48-
props,
49-
link,
50-
boids,
51-
interval,
52-
}
45+
Self { boids, interval }
5346
}
5447

55-
fn update(&mut self, msg: Self::Message) -> ShouldRender {
48+
fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> ShouldRender {
5649
match msg {
5750
Msg::Tick => {
5851
let Props {
5952
ref settings,
6053
paused,
6154
..
62-
} = self.props;
55+
} = *ctx.props();
6356

6457
if paused {
6558
false
@@ -71,36 +64,26 @@ impl Component for Simulation {
7164
}
7265
}
7366

74-
fn change(&mut self, props: Self::Properties) -> ShouldRender {
75-
if props == self.props {
76-
false
77-
} else {
78-
if props.generation != self.props.generation {
79-
// generation changed; restart from scratch.
80-
self.boids.clear();
81-
}
67+
fn changed(&mut self, ctx: &Context<Self>) -> ShouldRender {
68+
self.boids.clear();
8269

83-
let settings = &props.settings;
84-
self.boids
85-
.resize_with(settings.boids, || Boid::new_random(settings));
70+
let settings = &ctx.props().settings;
71+
self.boids
72+
.resize_with(settings.boids, || Boid::new_random(settings));
8673

87-
if settings.tick_interval_ms != self.props.settings.tick_interval_ms {
88-
// as soon as the previous task is dropped it is cancelled.
89-
// We don't need to worry about manually stopping it.
90-
self.interval = {
91-
let link = self.link.clone();
92-
Interval::new(settings.tick_interval_ms as u32, move || {
93-
link.send_message(Msg::Tick)
94-
})
95-
}
96-
}
74+
// as soon as the previous task is dropped it is cancelled.
75+
// We don't need to worry about manually stopping it.
76+
self.interval = {
77+
let link = ctx.link().clone();
78+
Interval::new(settings.tick_interval_ms as u32, move || {
79+
link.send_message(Msg::Tick)
80+
})
81+
};
9782

98-
self.props = props;
99-
true
100-
}
83+
true
10184
}
10285

103-
fn view(&self) -> Html {
86+
fn view(&self, _ctx: &Context<Self>) -> Html {
10487
let view_box = format!("0 0 {} {}", SIZE.x, SIZE.y);
10588

10689
html! {

examples/boids/src/slider.rs

+6-17
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use std::cell::Cell;
22
use yew::{
3-
html, web_sys::HtmlInputElement, Callback, Component, ComponentLink, Html, InputEvent,
4-
Properties, ShouldRender, TargetCast,
3+
html, web_sys::HtmlInputElement, Callback, Component, Context, Html, InputEvent, Properties,
4+
ShouldRender, TargetCast,
55
};
66

77
thread_local! {
@@ -28,34 +28,23 @@ pub struct Props {
2828
}
2929

3030
pub struct Slider {
31-
props: Props,
3231
id: usize,
3332
}
3433
impl Component for Slider {
3534
type Message = ();
3635
type Properties = Props;
3736

38-
fn create(props: Self::Properties, _link: ComponentLink<Self>) -> Self {
37+
fn create(_ctx: &Context<Self>) -> Self {
3938
Self {
40-
props,
4139
id: next_slider_id(),
4240
}
4341
}
4442

45-
fn update(&mut self, _msg: Self::Message) -> ShouldRender {
43+
fn update(&mut self, _ctx: &Context<Self>, _msg: Self::Message) -> ShouldRender {
4644
unimplemented!()
4745
}
4846

49-
fn change(&mut self, props: Self::Properties) -> ShouldRender {
50-
if self.props != props {
51-
self.props = props;
52-
true
53-
} else {
54-
false
55-
}
56-
}
57-
58-
fn view(&self) -> Html {
47+
fn view(&self, ctx: &Context<Self>) -> Html {
5948
let Props {
6049
label,
6150
value,
@@ -65,7 +54,7 @@ impl Component for Slider {
6554
min,
6655
max,
6756
step,
68-
} = self.props;
57+
} = *ctx.props();
6958

7059
let precision = precision.unwrap_or_else(|| if percentage { 1 } else { 0 });
7160

examples/counter/src/main.rs

+8-13
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use js_sys::Date;
22
use weblog::console_log;
3-
use yew::{html, Component, ComponentLink, Html, ShouldRender};
3+
use yew::{html, Component, Context, Html, ShouldRender};
44

55
// Define the possible messages which can be sent to the component
66
pub enum Msg {
@@ -9,19 +9,18 @@ pub enum Msg {
99
}
1010

1111
pub struct Model {
12-
link: ComponentLink<Self>,
1312
value: i64, // This will store the counter value
1413
}
1514

1615
impl Component for Model {
1716
type Message = Msg;
1817
type Properties = ();
1918

20-
fn create(_props: Self::Properties, link: ComponentLink<Self>) -> Self {
21-
Self { link, value: 0 }
19+
fn create(_ctx: &Context<Self>) -> Self {
20+
Self { value: 0 }
2221
}
2322

24-
fn update(&mut self, msg: Self::Message) -> ShouldRender {
23+
fn update(&mut self, _ctx: &Context<Self>, msg: Self::Message) -> ShouldRender {
2524
match msg {
2625
Msg::Increment => {
2726
self.value += 1;
@@ -36,26 +35,22 @@ impl Component for Model {
3635
}
3736
}
3837

39-
fn change(&mut self, _props: Self::Properties) -> ShouldRender {
40-
false
41-
}
42-
43-
fn view(&self) -> Html {
38+
fn view(&self, ctx: &Context<Self>) -> Html {
4439
html! {
4540
<div>
4641
<div class="panel">
4742
// A button to send the Increment message
48-
<button class="button" onclick={self.link.callback(|_| Msg::Increment)}>
43+
<button class="button" onclick={ctx.link().callback(|_| Msg::Increment)}>
4944
{ "+1" }
5045
</button>
5146

5247
// A button to send the Decrement message
53-
<button onclick={self.link.callback(|_| Msg::Decrement)}>
48+
<button onclick={ctx.link().callback(|_| Msg::Decrement)}>
5449
{ "-1" }
5550
</button>
5651

5752
// A button to send two Increment messages
58-
<button onclick={self.link.batch_callback(|_| vec![Msg::Increment, Msg::Increment])}>
53+
<button onclick={ctx.link().batch_callback(|_| vec![Msg::Increment, Msg::Increment])}>
5954
{ "+1, +1" }
6055
</button>
6156

examples/crm/src/add_client.rs

+9-22
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
use crate::Client;
2+
use yew::web_sys::{Event, HtmlInputElement, HtmlTextAreaElement};
23
use yew::{
3-
classes, html,
4-
web_sys::{Event, HtmlInputElement, HtmlTextAreaElement},
5-
Callback, Component, ComponentLink, Html, Properties, ShouldRender, TargetCast,
4+
classes, html, Callback, Component, Context, Html, Properties, ShouldRender, TargetCast,
65
};
76

87
#[derive(Debug)]
@@ -21,23 +20,19 @@ pub struct Props {
2120
}
2221

2322
pub struct AddClientForm {
24-
props: Props,
25-
link: ComponentLink<Self>,
2623
client: Client,
2724
}
2825
impl Component for AddClientForm {
2926
type Message = Msg;
3027
type Properties = Props;
3128

32-
fn create(props: Self::Properties, link: ComponentLink<Self>) -> Self {
29+
fn create(_ctx: &Context<Self>) -> Self {
3330
Self {
34-
props,
35-
link,
3631
client: Client::default(),
3732
}
3833
}
3934

40-
fn update(&mut self, msg: Self::Message) -> ShouldRender {
35+
fn update(&mut self, ctx: &Context<Self>, msg: Self::Message) -> ShouldRender {
4136
let client = &mut self.client;
4237
match msg {
4338
Msg::UpdateFirstName(value) => {
@@ -53,27 +48,19 @@ impl Component for AddClientForm {
5348
true
5449
}
5550
Msg::Add => {
56-
self.props.on_add.emit(std::mem::take(client));
51+
ctx.props().on_add.emit(std::mem::take(client));
5752
true
5853
}
5954
Msg::Abort => {
60-
self.props.on_abort.emit(());
55+
ctx.props().on_abort.emit(());
6156
false
6257
}
6358
}
6459
}
6560

66-
fn change(&mut self, props: Self::Properties) -> ShouldRender {
67-
if self.props == props {
68-
false
69-
} else {
70-
self.props = props;
71-
true
72-
}
73-
}
74-
75-
fn view(&self) -> Html {
76-
let Self { link, client, .. } = self;
61+
fn view(&self, ctx: &Context<Self>) -> Html {
62+
let link = ctx.link();
63+
let Self { client, .. } = self;
7764

7865
let update_name = |f: fn(String) -> Msg| {
7966
link.callback(move |e: Event| {

0 commit comments

Comments
 (0)