-
-
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 use_future
hook to make consuming futures as suspense easier
#2609
Conversation
packages/yew/src/suspense/hooks.rs
Outdated
#[hook] | ||
pub fn use_suspending_future<T, F>(f: F) -> SuspensionResult<T> | ||
where | ||
T: Clone + 'static, |
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.
Any way to avoid this Clone
bound?
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.
How about Rc<T>
?
Visit the preview URL for this PR (updated for commit 48eb65f): https://yew-rs-api--pr2609-use-suspending-futur-rf59mav0.web.app (expires Thu, 21 Apr 2022 17:18:59 GMT) 🔥 via Firebase Hosting GitHub Action 🌎 |
Size Comparison
|
What's your opinion on calling it simply |
That's a good idea, especially since it being in |
Sorry, I might not be able to review any pull request in detail until this weekend. For a memorised task (future), you may want to associate the task with a dependent type and rerun the task when the dependency changes and provide a method on the handle type to rerun the task when needed. #[hook]
pub fn use_suspending_future<F, T, O, D>(f: F, deps: D) -> SuspensionResult<UseSuspendingFutureHandle<O>>
where
F: FnOnce(&D) -> T,
T: 'static + Future<Output = O>
D: 'static + PartialEq
O: 'static
{
todo!()
} I will explain this in detail #2584 this weekend. |
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 like the hook, a lot. This should make it very easy to integrate data from a web requests into the component.
I tried implementing Code #[hook]
pub fn use_future_with_deps<F, D, T, O>(f: F, deps: D) -> SuspensionResult<UseFutureHandle<O>>
where
F: FnOnce(&D) -> T + 'static,
D: PartialEq + 'static,
T: Future<Output = O> + 'static,
O: 'static,
{
let output = use_state(|| None);
let suspension = {
let output = output.clone();
use_memo(
move |deps| {
Suspension::from_future(async move {
output.set(Some(f(deps).await));
})
},
deps,
)
};
if suspension.resumed() {
Ok(UseFutureHandle { inner: output })
} else {
Err((*suspension).clone())
}
} Errorerror[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> packages/yew/src/suspense/hooks.rs:50:56
|
50 | Suspension::from_future(async move {
| ________________________________________________________^
51 | | output.set(Some(f(deps).await));
52 | | })
| |_____________________^
|
note: first, the lifetime cannot outlive the anonymous lifetime #1 defined here...
--> packages/yew/src/suspense/hooks.rs:49:17
|
49 | / move |deps| {
50 | | Suspension::from_future(async move {
51 | | output.set(Some(f(deps).await));
52 | | })
53 | | },
| |_________________^
note: ...so that the types are compatible
--> packages/yew/src/suspense/hooks.rs:50:56
|
50 | Suspension::from_future(async move {
| ________________________________________________________^
51 | | output.set(Some(f(deps).await));
52 | | })
| |_____________________^
= note: expected `(functional::hooks::use_state::UseStateHandle<_>, _, &D)`
found `(functional::hooks::use_state::UseStateHandle<_>, _, &D)`
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that the type `impl std::future::Future<Output = [async output]>` will meet its required lifetime bounds...
--> packages/yew/src/suspense/hooks.rs:50:21
|
50 | Suspension::from_future(async move {
| ^^^^^^^^^^^^^^^^^^^^^^^
note: ...that is required by this bound
--> packages/yew/src/suspense/suspension.rs:137:58
|
137 | pub fn from_future(f: impl Future<Output = ()> + 'static) -> Self {
| ^^^^^^^ |
use_suspending_future
hook to make consuming futures as suspense easieruse_future
hook to make consuming futures as suspense easier
@hamza1311 you might clone output one more time, because futures needs static life time, you need to clone everything it consumes, like: let suspension = {
let output = output.clone();
use_memo(
move |deps| {
let output = output.clone(); # <-- here
Suspension::from_future(async move {
output.set(Some(f(deps).await));
})
},
deps,
)
}; |
@jetli I tried that, it ends up with the same error. I think it has something to do with |
@hamza1311 yes, deps needs to be cloned too, maybe wrap it in Rc::new, like use_effect_with_deps does. |
this compiles: #[hook]
pub fn use_future_with_deps<F, D, T, O>(f: F, deps: D) -> SuspensionResult<UseFutureHandle<O>>
where
F: FnOnce(&D) -> T + 'static,
D: PartialEq + 'static,
T: Future<Output = O> + 'static,
O: 'static,
{
let output = use_state(|| None);
let suspension = {
let output = output.clone();
use_memo(
move |deps| {
let f = f(deps);
Suspension::from_future(async move {
output.set(Some(f.await));
})
},
deps,
)
};
if suspension.resumed() {
Ok(UseFutureHandle { inner: output })
} else {
Err((*suspension).clone())
}
} |
Description
This PR introduced a new hook,
use_future
, to allow suspending a future and resuming with it's responseChecklist
cargo make pr-flow