Skip to content
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

Create a use_memo hook #2343

Closed
voidpumpkin opened this issue Jan 7, 2022 · 5 comments · Fixed by #2401
Closed

Create a use_memo hook #2343

voidpumpkin opened this issue Jan 7, 2022 · 5 comments · Fixed by #2401
Labels

Comments

@voidpumpkin
Copy link
Member

There are cases when you want to put all use_effect_with_deps dependencies into the dependency array.
Even including all Callbacks, as it is possible that your callback will become state and is going to have closure into an old state value.

But if that callback is created every time you render, that use_effect_with_deps is also going to trigger every time.
A solution would be to put that Callback into a use_memo hook, like react use_memo or use_callback.

Here is rough implementation:

use std::ops::Deref;

use yew::prelude::*;

/// Creates a memoized value
/// Takes a create_value_fn function that produces a value
/// And later only updates the value only if dependencies changed
///
/// This hook is beneficial when you don't want
/// children components to rerender every time parent renders
///
/// This hook mimics react [useCallback](https://reactjs.org/docs/hooks-reference.html#usecallback)
/// and [use_memo](https://reactjs.org/docs/hooks-reference.html#usememo)
pub fn use_memo<T, F, Dependents>(create_value_fn: F, deps: Dependents) -> UseStateHandle<T>
where
    T: 'static + Clone,
    F: FnOnce() -> T + Clone + 'static,
    Dependents: PartialEq + 'static,
{
    let value_handle = use_state(create_value_fn.clone());

    let value_handle_clone = value_handle.clone();
    use_effect_with_deps(
        move |_| {
            value_handle_clone.set(create_value_fn());
            || {}
        },
        deps,
    );

    value_handle
}
@futursolo
Copy link
Member

Yew already has use_ref which is use_memo without dependencies (renders once).

I think we should have some consistency in terms of naming. use_* without dependency and use_*_with_deps with dependency.

But I am not sure whether we should make use_ref use_memo and make with the dependency use_memo_with_deps or simply keep current naming and go with use_ref_with_deps.

@voidpumpkin
Copy link
Member Author

voidpumpkin commented Jan 7, 2022

@futursolo I don't think use_ref works as you need for your hook users to rerender on value change
In that sense use_memo works as we have noting like it then.

@futursolo
Copy link
Member

futursolo commented Jan 8, 2022

@futursolo I don't think use_ref works as you need for your hook users to rerender on value change
In that sense use_memo works as we have noting like it then.

What I am saying is that: use_ref(|| { ... }) = use_memo(|_| { ... }, ()).

So should it follow the *_with_deps like we had for other hooks? (Or simply remove use_ref in favour of use_memo.)

@voidpumpkin
Copy link
Member Author

@futursolo I don't think use_ref works as you need for your hook users to rerender on value change
In that sense use_memo works as we have noting like it then.

What I am saying is that: use_ref(|| { ... }) = use_memo(|_| { ... }, ()).

So should it follow the *_with_deps like we had for other hooks? (Or simply remove use_ref in favour of use_memo.)

I think you should not be able to set memo yourself, it would only get updated from changed dependencies. That is the main difference from use_ref.
use_ref is just a state storage that does not trigger rerenders.

@futursolo
Copy link
Member

futursolo commented Jan 10, 2022

I think you should not be able to set memo yourself

You cannot set use_ref value as well. It returns Rc<T>.

React's useRef equivalent is use_mut_ref, which is Rc<RefCell<T>> where you can set the value without triggering re-render.

My suggestion would be:

use_ref -> use_memo + optional re-render upon dependency changes.
use_mut_ref -> use_ref

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants