Home > database >  Calling async function in useEffect causes an ESLint error
Calling async function in useEffect causes an ESLint error

Time:10-24

I'm trying to call an async function in a callback in useEffect like this.

import {useState, useEffect} from 'react';
import Navbar from 'react-bootstrap/Navbar';

interface EnBoards {
  id: number
  name: string
  uri: string
}

const RedichanNav = (): JSX.Element => {

  const [enBoards, setEnBoards] = useState({});

  useEffect(() => {
    const fetchEnBoards = async () => {
      const response = await fetch('/api/en-boards');
      const enBoardsJson = await response.json() as EnBoards;
      setEnBoards(enBoardsJson);
    };
    fetchEnBoards(); // Here
  });

  return (
    <Navbar ></Navbar>);
};

export default RedichanNav;

Then I got an error.

  20:5   error    Promises must be awaited, end with a call to .catch, end with a call to .then with a rejection handler or be explicitly marked as ignored with the `void` operator
 @typescript-eslint/no-floating-promises

Then I changed the code like this.

  useEffect(async () => {
    const fetchEnBoards = async () => {
      const response = await fetch('/api/en-boards');
      const enBoardsJson = await response.json() as EnBoards;
      setEnBoards(enBoardsJson);
    };
    await fetchEnBoards();
  });

Then I got another error.

  14:13  error    Effect callbacks are synchronous to prevent race conditions. Put the async function inside:

useEffect(() => {
  async function fetchData() {
    // You can await here
    const response = await MyAPI.getData(someId);
    // ...
  }
  fetchData();
}, [someId]); // Or [] if effect doesn't need props or state

Learn more about data fetching with Hooks: https://reactjs.org/link/hooks-data-fetching  react-hooks/exhaustive-deps

My code is almost the same as FAQ and small demo and this article.

My .eslintrc.js

module.exports = {
 env: {
   browser: true,
   es2021: true,
 },
 extends: [
   'plugin:react/recommended',
   'airbnb',
   'airbnb/hooks',
   'plugin:@typescript-eslint/recommended',
   'plugin:@typescript-eslint/recommended-requiring-type-checking',
   'prettier',
 ],
 parser: '@typescript-eslint/parser',
 parserOptions: {
   ecmaFeatures: {
     jsx: true,
   },
   ecmaVersion: 12,
   sourceType: 'module',
   tsconfigRootDir: __dirname,
   project: ['./tsconfig.json'],
 },
 plugins: [
   'react',
   '@typescript-eslint',
 ],
 "ignorePatterns": [
   ".eslintrc.js"
 ],
 rules: {
   'semi': ['error', 'always'],
   'no-use-before-define': "off",
   "@typescript-eslint/no-use-before-define": "off",
   'import/prefer-default-export': "off",
   'import/extensions': [
       'error',
       {
         js: 'never',
         jsx: 'never',
         ts: 'never',
         tsx: 'never',
       },
     ],
     'react/jsx-filename-extension': [
       'error',
       {
         extensions: ['.jsx', '.tsx'],
       },
     ],
     'react/react-in-jsx-scope': 'off',
     'no-void': [
       'error',
       {
         allowAsStatement: true,
       },
     ],
     "react/function-component-definition": [
       2,
       {
         "namedComponents": "arrow-function"
       }
     ]
 },
 settings: {
   'import/resolver': {
     node: {
       paths: ['src'],
       extensions: ['.js', '.jsx', '.ts', '.tsx']
     },
   },
 },
};

Enmironment

  • MacOS 12.5
  • Node.js 18.7.0
  • TypeScript 4.8.4
  • React 18.2.0
  • React-Bootstrap 2.5.0
  • ESLint 8.25.0
  • @typescript-eslint/eslint-plugin 5.39.0
  • eslint-plugin-react-hooks 4.6.0

Thank you to read. Can anyone solve this?

CodePudding user response:

The first time you wrote the code it was right. Reading the error you got seems like you needed to add an try catch block to you function, like:

   useEffect(() => {
        const fetchEnBoards = async () => {
          try {  //This
          const response = await fetch('/api/en-boards');
          const enBoardsJson = await response.json() as EnBoards;
          setEnBoards(enBoardsJson);
          catch(err) {
          console.log(err)
          }
        };
        fetchEnBoards(); // Here
      });

CodePudding user response:

Looks like you need to read async await

useEffect(() => {
    const fetchEnBoards = async () => {
      const response = await fetch('/api/en-boards');
      const enBoardsJson = await response.json() as EnBoards;
      setEnBoards(enBoardsJson);
    };
    fetchEnBoards()
    .then((response)=>
    console.log("In then block"))
    .catch((err)=>
    console.log("In catch block"))
  });
  • Related