Next.js Discord

Discord Forum

await isn't allowed in non-async function

Answered
Brown bear posted this in #help-forum
Open in Discord
Avatar
Brown bearOP
when i build nextjs project, the error throw like below

await isn't allowed in non-async function

how can i fix it?

my nextjs version is 14.1.0


Error: 
  x await isn't allowed in non-async function
     ,-[547:1]
 547 | /* harmony import */ var _s3_client__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(64899);
 548 | /* harmony import */ var private_next_rsc_action_validate__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(11782);
 549 | var __webpack_async_dependencies__ = __webpack_handle_async_dependencies__([next_mdx_remote_serialize__WEBPACK_IMPORTED_MODULE_5__]);
 550 | next_mdx_remote_serialize__WEBPACK_IMPORTED_MODULE_5__ = (__webpack_async_dependencies__.then ? (await __webpack_async_dependencies__)() : __webpack_async_dependencies__)[0];
     :                                                                                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 551 | /* __next_internal_action_entry_do_not_use__ {"13017dec98ff5b6e9091105bc00639c37f7d9e4f":"getJsonFile","3684a9620e09dd0134494037197f5b1b84378674":"getPresignedUrl","70b69401391c40c781a43ea5e68fce93ca3b3cc9":"putObject","863c555170626c52b7221c2bd941b3d895ca9f7f":"uploadFile","9db54832f44a7b942044898e8c2109e31246dda9":"listFilesInS3Folder","d0f7fc8c4507238f6349b5b62668b2f87ea29698":"uploadFileToS3","f447554fd241f4d19754f321597e47291541554b":"getMdxFile"} */ 
 552 | 
     `----
Answered by Z4NR34L
when you want to fetch data in useEffect, be sure that function uses client-side apis like fetch method. to make that works you need to create an state which will take data fetched from API for example just like:

'use client'

export function Component() {
const [data, setData] = useState(undefined)

useEffect(() => {
 fetch('https://api.vercel.app/blog')
    .then((response) => response.json())
    .then((_data) => {
      setData(_data)
    });
}, [])

return (
  <div>
    <pre>{JSON.stringify(data, null, 2)</pre>
  </div>
)
}


this solution shall fetch mock api from client's browser and display data in JSON format inside <pre> 🙂

Hope this helps, if you will run into any issues feel free to ping me there
View full answer

20 Replies

Avatar
Brown bearOP
Avatar
make the function async where u fetch data
Avatar
Brown bearOP
but this kind of grammar not work

  useEffect(async () => {
    await fetchData();
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, []);
Avatar
Basset Artésien Normand
why do you need useEffect? if its a server component cant you just fetch the data anyway
export default async function Page() {
  const data = await fetchData()
  return (
    <html here>
  )
}
Avatar
European hornet
even if is client component, useEffect should not be async
Avatar
Brown bearOP
this code is full code of my error thrown
Image
saveProduct and handleFileChange function throw the error maybe
Avatar
Basset Artésien Normand
Can't really do much with that.
Avatar
when you want to fetch data in useEffect, be sure that function uses client-side apis like fetch method. to make that works you need to create an state which will take data fetched from API for example just like:

'use client'

export function Component() {
const [data, setData] = useState(undefined)

useEffect(() => {
 fetch('https://api.vercel.app/blog')
    .then((response) => response.json())
    .then((_data) => {
      setData(_data)
    });
}, [])

return (
  <div>
    <pre>{JSON.stringify(data, null, 2)</pre>
  </div>
)
}


this solution shall fetch mock api from client's browser and display data in JSON format inside <pre> 🙂

Hope this helps, if you will run into any issues feel free to ping me there
Answer
Avatar
The simpliest solution is to use SWR - https://swr.vercel.app/ which is doing pretty similar trick but in much much less complicated code
Example with SWR:
import useSWR from 'swr'
 
function Profile() {
  const { data, error, isLoading } = useSWR('/api/user', fetcher)
 
  if (error) return <div>failed to load</div>
  if (isLoading) return <div>loading...</div>
  return <div>hello {data.name}!</div>
}
Avatar
fully agreed with Z4NR34L here, just an extra note that if you want to run an async function inside useEffect but not want to use the .then syntax, you can use an IIFE

useEffect(() => {
  (async () => {
    await doSomething();
  })();
}, [...]);


but for data fetching, use either server component or a fetching library (react-query/swr)
Avatar
Solution that @joulev provided is good as well - but there is need to remember that it stills need to be compatible with client API, so no database calls (unless you are using supabase where you can do that haha), or server-side packages
Avatar
Brown bearOP
thank you so much guys!
i will try these thing!
Avatar
Brown bearOP
oh, can i use react query instead of swr in my case?
when i search about performance, react query's performance much better
Avatar
swr is simpler, react query has more features, but in terms of performance they are about the same
Avatar
I always tell that anything's performance depends on dev that is using it :lolsob: I had met too many cases so far I think haha
Avatar
Brown bearOP
oh thank you your advises!
Avatar
if you consider this case as closed please remember to mark message with solution:
Right click -> Apps -> Mark Solution