crimsonpython24
crimsonpython24

Reputation: 2383

Cannot use Hook Inside React Function

I faced an invalid hook call error when using the useEffect hook. The docs only specified that this problem occurred because of either a version mismatch or my function call is incorrect.

Can anyone please check which part did I made my mistake?

import React, { useState, useEffect } from "react";
import "antd/dist/antd.css";
import { Typography, Card, Avatar, Row, Col, Tooltip } from "antd";
import {
  UserOutlined,
  BookOutlined,
  LogoutOutlined,
  SettingOutlined
} from "@ant-design/icons";

const { Text } = Typography;

export default function ProfileCard() {
  const [error, setError] = useState(null);
  const [isLoaded, setIsLoaded] = useState(false);
  const [items, setItems] = useState([]);

  useEffect(() => {
    fetch("/accounts/api/" + username)
      .then(res => res.json())
      .then(
        (result) => {
          setIsLoaded(true);
          setItems(result.items);
        },
        (error) => {
          setIsLoaded(true);
          setError(error);
        }
      )
  }, [])

  return (
    <>
      <Card
        size="small"
        style={{ width: 300 }}
        actions={[...]}
      >
        <Row justify="center" style={{ marginBottom: -3 }}>
          <Col>
            <Text strong style={{ fontSize: 17 }}>
              { items.username }
            </Text>
          </Col>
        </Row>
      </Card>
    </>
  );
}

Please assume that all dependencies are installed and username is a predefined string.

Sincerely,

cpy24

Upvotes: 1

Views: 138

Answers (5)

crimsonpython24
crimsonpython24

Reputation: 2383

I really appreciated those who tried to answer my question. It turned out that I loaded this component inside another and that's a violation of rules. Upvoted to all those that tried to help out along the way.

Upvotes: 0

Stefano Giometti
Stefano Giometti

Reputation: 433

IIRC you have to declare the function inside the useEffect

  useEffect(() => {
     const fetchData = async () => {
        try {
           let response = await fetch(`/accounts/api/${username}`);
           let result = await response.json();

           setIsLoaded(true);
           setItems(result.items);
        } catch(err) {
           console.error(err);
           setIsLoaded(true);
           setItems(err);
        }
     };

     fetchData();
  }, []);

Upvotes: 1

daniel93
daniel93

Reputation: 301

what are the versions of react and react-dom? (I cannot comment)

Upvotes: 1

Roy Chan
Roy Chan

Reputation: 285

Try wrapping the fetch with a useCallback hook as suggested in the comments

const fetchData = useCallback(() => {
   fetch("/accounts/api/" + username)
      .then(res => res.json())
      .then(
        (result) => {
          setIsLoaded(true);
          setItems(result.items);
        },
        (error) => {
          setIsLoaded(true);
          setError(error);
        }
      )
}, [])

useEffect(() => {
  fetchData()
}, [fetchData])

Upvotes: 1

kyun
kyun

Reputation: 10264

useEffect(() => {
    fetch("/accounts/api/" + username)
      .then(res => res.json())
      .then((result) => {
          setIsLoaded(true);
          setItems(result.items);
      })
      .catch((error) => {
          setIsLoaded(true);
          setError(error);
      });
  }, []);

use catch for Error.

Upvotes: 1

Related Questions