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

[Feature]: exporting useTimout? #1094

Open
manudeli opened this issue Jul 16, 2024 · 7 comments
Open

[Feature]: exporting useTimout? #1094

manudeli opened this issue Jul 16, 2024 · 7 comments
Assignees
Milestone

Comments

@manudeli
Copy link
Member

Package Scope

@suspensive/react

Description

useTimeout could suspensive interfaces?

Possible Solution

No response

etc.

No response

@bigsaigon333
Copy link
Collaborator

bigsaigon333 commented Jul 27, 2024

@manudeli, can you tell me more about what "suspensive interfaces" mean?

@manudeli
Copy link
Member Author

I changed description for this repository like below after #1072

AS IS

"Packages to use React Suspense easily"

TO BE

"Manage asynchronous operations, timing, error handling, detecting intersection of elements, and caching easily"

So I thought useTimeout could be "Suspensive interfaces(timing)"

@bigsaigon333 But I want to check whether this vision is good for you too.

@bigsaigon333
Copy link
Collaborator

What a nice discussion! I read #1072 thoroughly and agree with this description 100%.

"Manage asynchronous operations, timing, error handling, detecting intersection of elements, and caching easily"

However, I wanted to add some words after easily, which is and declaratively. The useTimeout hook can be provided by any kind of utility package, and in fact, react-use already provides a useTimeout hook.

I believe that we can provide not only any hook related to asynchronous operations but also declarative React components corresponding to those hooks. The relationship between useSuspenseQuery and <SuspenseQuery /> is a good example.

useTimeout -> <Timeout /> (or <Delay /> may be enough ...?)

@manudeli
Copy link
Member Author

However, I wanted to add some words after easily, which is and declaratively

I added it now! thanks for your feedback!

@manudeli
Copy link
Member Author

manudeli commented Jul 28, 2024

I believe that we can provide not only any hook related to asynchronous operations but also declarative React components corresponding to those hooks. The relationship between useSuspenseQuery and is a good example.

useTimeout -> (or may be enough ...?)

I didn't think about <Timeout />, Cool, but I'm curious implementation of . Let's continue to discuss together how we make it and why we need to support it.

@bigsaigon333
Copy link
Collaborator

Well, I just thought using use api from React!

  1. useTimeout will use a Promise that resolves when a specified timeout has elapsed.
  2. <Timeout /> will use use API to expose the promise-based behaviour within a declarative component.

This below is just pseudo code.

import { use } from 'react';

function createTimeoutPromise(duration) {
  return new Promise(resolve => setTimeout(resolve, duration));
}

function Timeout({ duration, children, fallback }) {
  use(createTimeoutPromise(duration)); // Suspend until promise resolves
  return <>{children}</>; // Render children after the timeout
}

I'm trying to understand where a component would be particularly useful, but I haven't come across a specific example that demonstrates its necessity. 😭
Using a declaratively would be nice for me, and I’m pretty sure I would use it quite often,
but I doubt others would feel the same way.

What do you think, @manudeli?

@manudeli
Copy link
Member Author

manudeli commented Jul 29, 2024

I'm trying to understand where a component would be particularly useful, but I haven't come across a specific example that demonstrates its necessity. 😭

Sadly, in my opinion, It's the most important thing that finding example use cases!

import { use } from 'react';

function createTimeoutPromise(duration) {
  return new Promise(resolve => setTimeout(resolve, duration));
}

function Timeout({ duration, children, fallback }) {
  use(createTimeoutPromise(duration));
  return <>{children}</>;
}

Good idea, but I think this will make circular suspending on render.

  1. Timeout render
  2. createTimeoutPromise will be executed
  3. use(promise) will make suspending (throw this pending promise)
  4. Suspense will try re-render Timeout
  5. createTimeoutPromise will be executed
  6. use(promise) will make suspending (throw this pending promise)
  7. ... (infinite loop)

I fixed it as below. but it have problem that we cannot control timing promise start time

import { use } from 'react';

function createTimeoutPromise(duration) {
  return new Promise(resolve => setTimeout(resolve, duration));
}

const promiseTimeout = createTimeoutPromise(duration) // single source of promise should be guaranteed to suspend only one time

function Timeout({ duration, children, fallback }) {
  use(promiseTimeout);
  return <>{children}</>;
}

So we can make it as cache on mount using @tanstack/react-query or @suspensive/cache to cache promise to suspend only one time on mount

import { useCache } from '@suspensive/cache';

function createTimeoutPromise(duration) {
  return new Promise(resolve => setTimeout(resolve, duration));
}

function TimeoutOnlyOneTime({ duration, children, fallback }) {
  useCache({
    cacheKey: ["cached"],
    cacheFn: () => createTimeoutPromise(duration)
  }) // only one time make promise on mount of TimeoutOnlyOneTime
  return <>{children}</>; // Render children after the timeout
}

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

No branches or pull requests

5 participants