-
-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add useful methods to UseStateHandle
& UseReducerHandle
#3422
base: master
Are you sure you want to change the base?
Conversation
Visit the preview URL for this PR (updated for commit 174d139): https://yew-rs-api--pr3422-add-handle-methods-dx5xc4eu.web.app (expires Thu, 05 Oct 2023 20:54:58 GMT) 🔥 via Firebase Hosting GitHub Action 🌎 |
Benchmark - SSRYew Master
Pull Request
|
Size Comparison
✅ None of the examples has changed their size significantly. |
/// Returns the inner value of the handle. | ||
pub fn get(&self) -> Rc<T> { | ||
// Safety: `UseStateReducer<T>` is `repr(transparent)` and only contains `T` | ||
unsafe { transmute(self.inner.get()) } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we avoid the transmute somehow?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
not really, this transmute converts between Rc<UseStateReducer<T>>
and Rc<T>
, there's not much you can do with a value inside an Rc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You would need to convert Rc<UseStateReducer<T>> -> Rc<T>
(assuming T
is not guaranteed to be Clone
) some other way then (maybe via Any
?). I think using repr(transparent)
was a brilliant idea for Rc
s and now I hope Rust makes it like a safe trait / Rc
function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not in favour of this pull request.
We have discussed in some previous pull requests. How a state is stored should be an implementation detail. Not exposing this allows us to switch the underlying implementation at a later time.
e.g.:
To implement concurrent mode, we will need to have multiple schedulers and states need to be associated with a scheduler ID .
I am not exactly settled on how this would be associated.
This pull request rules out the following possibility.
struct UseStateReducer<T> {
inner: T,
scheduler_id: Id,
}
The PR does restrict the flexibility in implementation, but on the other hand, how likely is the implementation to change? The current approach works just fine, obtaining/setting the value doesn't require much indirection, and the new methods will allow for easier usage of non(-trivially)-clonable types in the aforementioned handle types. |
@futursolo Provide other solutions of being able to encapsulate/not clone
#[derive(Clone, ...)] // also ImplicitClone
struct UseStateValue<T> {
inner: Rc<T>, // using same `repr(transparent)`/`transmute` trick
}
impl Deref for UseStateValue<T> {
type Target = T;
...
}
Also possible that |
The medium case isn't good because oftentimes the value needs to be cloned after getting it out of the state, forcing T to be Clone when it can be avoided. It's either that or recreating the Rc that we just took the value out of. Yew playground has a component that suffers from this exact same thing today when attaching the change listener to Monaco editor Concurrent mode, when implemented, will most likely come with breaking changes of its own. I'd rather remove these methods then, providing a suitable alternative, than not add them in the first place |
Description
This PR adds:
UseStateHandle::get
&UseReducerHandle::get
that return the contained value of the handle in the form in which it's stored internally: in an Rc; These 2 methods will make it easier to work with non(-trivially)-clonable types in said containers;UseStateHandle::into_inner
&UseReducerHandle::into_inner
that consume the handle and return its 2 main parts: the inner value and the setter/dispatcher associated with the handle. These methods will allow for avoiding cloning in certain contexts where one would have to useget()
+setter()
/dispatcher()
otherwise.Checklist