From 6adfa74000f434c9d6a1545d20955560829416be Mon Sep 17 00:00:00 2001 From: Henry Zimmerman Date: Mon, 12 Aug 2019 07:43:09 -0400 Subject: [PATCH 1/3] add on_mount --- src/html/mod.rs | 4 ++++ src/html/scope.rs | 9 ++++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/src/html/mod.rs b/src/html/mod.rs index 12edadbdec1..d45ea3306fb 100644 --- a/src/html/mod.rs +++ b/src/html/mod.rs @@ -24,6 +24,10 @@ pub trait Component: Sized + 'static { type Properties: Properties; /// Initialization routine which could use a context. fn create(props: Self::Properties, link: ComponentLink) -> Self; + /// Called after the component has been attached to the VDOM and it is safe to receive messages + /// from agents. Any changes made to the state that `view` relies on will not be apparent + /// immediately as this method does not trigger a rerender. + fn on_mount(&mut self) {} /// Called everytime when a messages of `Msg` type received. It also takes a /// reference to a context. fn update(&mut self, msg: Self::Message) -> ShouldRender; diff --git a/src/html/scope.rs b/src/html/scope.rs index 39ce87c1e68..2492f9d1814 100644 --- a/src/html/scope.rs +++ b/src/html/scope.rs @@ -112,6 +112,11 @@ struct CreatedState { } impl> CreatedState { + /// Called once immediately after the component is created. + fn mounted(mut self) -> Self { + self.component.on_mount(); + self + } fn update(mut self) -> Self { let mut next_frame = self.component.view(); let node = next_frame.apply(&self.element, None, self.last_frame, &self.env); @@ -178,7 +183,9 @@ where fn run(self: Box) { let current_state = self.shared_state.replace(ComponentState::Processing); self.shared_state.replace(match current_state { - ComponentState::Ready(state) => ComponentState::Created(state.create().update()), + ComponentState::Ready(state) => { + ComponentState::Created(state.create().update().mounted()) + }, ComponentState::Created(_) | ComponentState::Destroyed => current_state, ComponentState::Empty | ComponentState::Processing => { panic!("unexpected component state: {}", current_state); From 617d5693da3e914214332b5763460bebaf47d48a Mon Sep 17 00:00:00 2001 From: Henry Zimmerman Date: Mon, 12 Aug 2019 08:43:57 -0400 Subject: [PATCH 2/3] use spread operator in CreatedState::update --- src/html/scope.rs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/html/scope.rs b/src/html/scope.rs index 2492f9d1814..7252059a39d 100644 --- a/src/html/scope.rs +++ b/src/html/scope.rs @@ -125,11 +125,8 @@ impl> CreatedState { } Self { - env: self.env, - component: self.component, last_frame: Some(next_frame), - element: self.element, - occupied: self.occupied, + ..self } } } From 1ef1b1a5b278e77f2236a1ce4e21c6a99f578aa7 Mon Sep 17 00:00:00 2001 From: Henry Zimmerman Date: Mon, 12 Aug 2019 22:28:20 -0400 Subject: [PATCH 3/3] changed on_mount to mounted, clean up update's self return, support rerendering on mounted --- src/html/mod.rs | 6 +++--- src/html/scope.rs | 14 ++++++++------ 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/html/mod.rs b/src/html/mod.rs index d45ea3306fb..3fe4f0018b8 100644 --- a/src/html/mod.rs +++ b/src/html/mod.rs @@ -25,9 +25,9 @@ pub trait Component: Sized + 'static { /// Initialization routine which could use a context. fn create(props: Self::Properties, link: ComponentLink) -> Self; /// Called after the component has been attached to the VDOM and it is safe to receive messages - /// from agents. Any changes made to the state that `view` relies on will not be apparent - /// immediately as this method does not trigger a rerender. - fn on_mount(&mut self) {} + /// from agents but before the browser updates the screen. If true is returned, the view will + /// be re-rendered and the user will not see the initial render. + fn mounted(&mut self) -> ShouldRender { false } /// Called everytime when a messages of `Msg` type received. It also takes a /// reference to a context. fn update(&mut self, msg: Self::Message) -> ShouldRender; diff --git a/src/html/scope.rs b/src/html/scope.rs index 7252059a39d..91292759d3d 100644 --- a/src/html/scope.rs +++ b/src/html/scope.rs @@ -114,9 +114,13 @@ struct CreatedState { impl> CreatedState { /// Called once immediately after the component is created. fn mounted(mut self) -> Self { - self.component.on_mount(); - self + if self.component.mounted() { + self.update() + } else { + self + } } + fn update(mut self) -> Self { let mut next_frame = self.component.view(); let node = next_frame.apply(&self.element, None, self.last_frame, &self.env); @@ -124,10 +128,8 @@ impl> CreatedState { *cell.borrow_mut() = node; } - Self { - last_frame: Some(next_frame), - ..self - } + self.last_frame = Some(next_frame); + self } }