yewstack / yew

Rust / Wasm framework for creating reliable and efficient web applications
https://yew.rs
Apache License 2.0
30.77k stars 1.43k forks source link

Add a props assignment+render helper function #631

Closed hgzimmerman closed 5 years ago

hgzimmerman commented 5 years ago

Description

**I'm submitting a feature request

I've seen a pattern where when you have props stored directly as part of your model. When I, and I assume others implement change, I typically come across something like:

fn change(&mut self, props: Self::Properties) -> ShouldRender {
    self.props = props;
    true
}

This is unfortunate in that it always causes a re-render. I'm guilty of doing this because I don't want to write the boilerplate to check if the props actually are different.

I propose adding a utility function to yew::utils that assigns a value if they differ and returns true if the value was replaced.

Examples

fn change(&mut self, props: Self::Properties) -> ShouldRender {
    // Will render only if the props were assigned.
    assign_if_different(&mut self.props, props)
}
fn change(&mut self, props: Self::Properties) -> ShouldRender {
    // Will render if any of the props were assigned, short circuits when one field is the same.
    assign_if_different(&mut self.field1, props.field1)
        &&  assign_if_different(&mut self.field2, props.field2)
        &&  assign_if_different(&mut self.field3, props.field3)
}

Benefits

Drawbacks

jstarry commented 5 years ago

😆 "yew-sers"

This is sweet! I think this would make for a nice "tip" in the future book for those who tire of writing lots of boilerplate but I'm not sure it's needed inside the framework. If we did add something like this, we would want it to be namespaced.

I do think it's a good idea to promote the use of storing props in the model. I wonder if our examples are lacking on this... Maybe we can focus on improving example quality to promote good usage patterns. Thoughts?

hgzimmerman commented 5 years ago

Oh, its absolutely not needed. Because its so simple and easy to implement as part of a project, the only benefit of putting it in yew is enhanced discoverability, and adding to a common terminology that is shared by anyone using yew.

I'll move it to its own module in the PR, but feel free to close it if you don't think it belongs, I won't take any offense.

StevenDoesStuffs commented 5 years ago

I think we should have a bind macro that goes something like this:

fn change(&mut self, props: Self::Properties) -> ShouldRender {
    bind!{self.foo = props.foo; self.thing.bar = props.bar};
}
hgzimmerman commented 5 years ago

As with the associated PR, I'm closing this in favor of getting this functionality via an external crate.