简体   繁体   中英

react - how to make hook async

This is my component.

const DashboardContext = React.createContext()

function DashboardStateProvider({ children }) {
    const Provider = DashboardContext.Provider
    return (
      <WithSubscription Provider={Provider} connectedAccount={wallet.account}>
        {children}
      </WithSubscription>
    )
}

async function WithSubscription({ Provider, connectedAccount, children }) {
  const { data } =  await asyncCallHere()

  return ( <Provider value={{ treasury }}> {children} </Provider> )
}

function useDashboardState() {
  return useContext(DashboardContext)
}

export { DashboardStateProvider, useDashboardState }

In the code, one can see asyncCallHere . Before this code, asyncCallHere was synchronous which means I had no mistake in the code. But I need it to make async, so I had to add async to withSubscription function. Hope the code makes sense.

The problem is that because I put await and async there, it results in the following error:

Unhandled Rejection (Error): Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:

  1. You might have mismatching versions of React and the renderer (such as React DOM)
  2. You might be breaking the Rules of Hooks
  3. You might have more than one copy of React in the same app See facebook dev page for tips about how to debug and fix this problem.

I'd appreciate the quick answer to fix this, due to the fact that I am not react developer and I don't intend to understand what's happening there in deep other than to fix it.

Hooks cannot be async.

You always need to return sync data from the hook.

However, if you want to do some async operation inside the hook, you can do it inside useEffect to store the data in the hook state and return that data from the hook itself.

import React, {useEffect, useState} from 'react'

function useAsyncCallHere() {
  const [data, setData] = useState(null)

  useEffect(() => {
    async function getData() {
      const response = await asyncCallHere()
      setData(response.data)
    }

    getData()
  }, [])

  return data
}

function WithSubscription({ Provider, connectedAccount, children }) {
  const data = useAsyncCallHere()

  return ( <Provider value={{ data }}> {children} </Provider> )
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM