reactjs/rfcs

Suspense hook API

yisar opened this issue · 3 comments

yisar commented

We lack a friendly suspense API for data request, and the current Suspense component is more suitable for lazy import component.

Motivation

Suspense component provides a good nesting, but it loses part of the reuse ability, which is similar to Context. The advantage of ``Consumer is nesting, but the advantage of useContext is reuse

Suspense needs powerful nesting and reuse to become useful.

Example

function fetchUsers (pageSize) {
  console.log('fetch users from clicli...')
  return fetch(`https://api.clicli.us/users?level=4&page=1&pageSize=${pageSize}`)
    .then(res => res.json())
    .then(data => {
      return data.users
    })
}

const useUser = createSuspense(fetchUsers)

function App () {
  const [pageSize, setPageSize] = useState(1)
  const users = useUser(pageSize)

  return (
    <main>
      <h1>Fetching clicli users</h1>
      <button onClick={() => setPageSize(pageSize + 1)}>Click {pageSize}</button>
      {users.map(user => (
        <img src={`https://q1.qlogo.cn/g?b=qq&nk=${user.qq}&s=640`} />
      ))}
    </main>
  )
}

Implement

It's hard for me to give an accurate implementation, but it might look like this:

export function createSuspense(promise) {
  let pending = true
  let result
  let backupData = null

  return data => {
    if (backupData !== data) {
      pending = true
      backupData = data
    }
    if (pending) {
      throw promise(data).then(res => {
        pending = false
        result = res
      })
    } else {
      return result
    }
  }
}

I think it might be a good idea to imagine an API like the one above.
What do you think?

It is a good point, but I don't think it is necessary to be added in react top-level api.

You can use your code though. And there is some libraries which will more likely accept this rfc like regionjs/region-core and zeit/swr

yisar commented

@dancerphil

As you said, a similar API does not need to be provided by react

The Suspense component is not needed, too. Users can actively throw promise outside.

But I think the idea of react is to provide these APIs as much as possible, such as the usetransition. Many libraries have similar implementations, but they are not low-level enough.

But I think the idea of react is to provide these APIs as much as possible

no, the philosophy of the react is to give fundamental and low level as possible api. higher levels of library abstraction, will give restrictions for the user level of abstraction.

low api of course enrage, but in the end we get a huge number of libraries of a higher level, which makes the react so good =)