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

Is it possible to make useDeferredValue to actually do something? #3649

Open
zsolt-dev opened this issue Aug 7, 2022 · 7 comments
Open

Is it possible to make useDeferredValue to actually do something? #3649

zsolt-dev opened this issue Aug 7, 2022 · 7 comments

Comments

@zsolt-dev
Copy link

It looks like useDeferredValue does nothing in Preact. This is a code from compat:

export function useDeferredValue(val) {
	return val;
}

Is it possible to implement useDeferredValue it in Preact? If yes, is there a plan for it? What would be a preferred workaround right now?

Thank you

@JoviDeCroock
Copy link
Member

I mean, what is your use case for useDeferredValue we aren't rendering async so it can't really have an implementation afaict

@zsolt-dev
Copy link
Author

@JoviDeCroock

I was thinking maybe putting returning the last value and return current value after setTimeout: 0 ?

On server it would return new value straight away, like now...

Would that work? If you I could provide a PR.

@JoviDeCroock
Copy link
Member

I personally don't really see the use of that 😅 our renders aren't interruptable and are prioritized according to depth so tearing can't occur, the value returned there is always the correct value for the current subtree. I am not entirely sure I get the use case here, if I understand correctly you are looking for a way to have the value of the previous render available while rendering and then when effects, ... run you want to leverage the current value.

@zsolt-dev
Copy link
Author

@JoviDeCroock

Yes, basically rerender with the old value (so everything else than the expensive stuff) and then change the value and rerender just the expensive stuff. The idea behind it is that user gets the feedback right away and the expensive stuff gets rerendered later.

@gaearon had some ideas about it too: #3510 (comment)

@ekwoka
Copy link
Contributor

ekwoka commented Aug 23, 2022

@JoviDeCroock

Yes, basically rerender with the old value (so everything else than the expensive stuff) and then change the value and rerender just the expensive stuff. The idea behind it is that user gets the feedback right away and the expensive stuff gets rerendered later.

@gaearon had some ideas about it too: #3510 (comment)

The way to do that in preact would be with a useEffect.

@zsolt-dev
Copy link
Author

Thank you @ekwoka for your input.

Yes, you are right that useEffect is a way to achieve this.

But this issue is about preact-compat. When someone is switching from react code and expects useDeferredValue to do something. And since preact is not async, my proposed solution provides similar functionality without async.

@gaearon can you please explain what did you mean in your comment: #3510 (comment) ?

I would be happy to create a PR for this.

@CodyJasonBennett
Copy link

This is effectively what the hook does and how I implemented it in react-nylon:

function useDeferredValue<T>(value: T): T {
  const [deferredValue, setDeferredValue] = useState(value)

  useEffect(() => startTransition(() => setDeferredValue(value)), [value])

  return deferredValue
}

Since there's no async scheduler in Preact, you can omit startTransition (no-op), but the magic comes from useEffect which defers the callback via requestAnimationFrame.

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

No branches or pull requests

5 participants