Я получаю сообщение об ошибке «ReferenceError: useState не определено»

Компилятор инструментов разработчика в настоящее время выдает мне эту ошибку:

ReferenceError: useState is not defined

С помощью этого блока кода я пытаюсь получить имена и изображения нескольких игроков из API НФЛ. Затем отобразите эту информацию в виде карточек, по которым люди могут щелкнуть по имени и перейти на страницу каждого отдельного игрока.

Это код компонента, с которым я работаю:

import { Link } from "react-router-dom";
import _navbar from "../NavBar/navbar";
import styles from './card.module.css';

export default function _quarterbacksPage() {
    const quarterbacks = [3139477, 4241479, 3918298, 3915511, 2577417];

    const options = {
        method: 'GET',
        headers: {
            'x-rapidapi-key': 'secretkey',
            'x-rapidapi-host': 'nfl-api-data.p.rapidapi.com'
        }
    };
    for (let i = 0; i < quarterbacks.length; i++){
            const [img, setImg] = useState();
            const [name, setName] = useState();
    
        
            const imageUrl = "https://nfl-api-data.p.rapidapi.com/nfl-ath-img?id = " + quarterbacks[i];
            const fetchImage = async () => {
            fetch(imageUrl, options)
            .then(response => response.json())
            .then(response => {
                const data = response.image.href;
                new Blob([data], {type: 'image/png' });  
                setImg(data);
                
            })
          };
    
    
            const FullNameUrl = 'https://nfl-api-data.p.rapidapi.com/nfl-ath-fullinfo?id=' + quarterbacks[i];
            const fetchFullName = async () => {
                fetch(FullNameUrl, options)
                .then(response => response.json())
                .then(response => {
                    const data = response.athlete.fullName;
                    setName(data);
                
                })
            };
    
        useEffect(() => {
            fetchImage();
            fetchFullName();
        }, []);
    }


    return (
        <>
            <div>
                <_navbar />
                {quarterbacks.map((quarterback) => (
                    <>
                        <img className = {styles.cardImage} src = {img} alt = "profile picture"></img>
                        <Link key = {quarterback} to = {`/quarterbacks/${quarterback}`}>
                            <h2 className = {styles.cardTitle}>{name}</h2>
                        </Link>
                    </>
                ))}
            
            </div>
        </>
    );
}

Этот блок кода я использовал для всех своих маршрутов:

import React from 'react'
import ReactDOM from 'react-dom/client'
import { createBrowserRouter, RouterProvider } from 'react-router-dom';

import AnalyticsNow from'./pages/analyticsNow.jsx';
import _quarterbackPage from './pages/quarterback.jsx';
import _quarterbacksPage from './pages/quarterbacks.jsx';
import _runningbackPage from './pages/runningback.jsx';
import _runningbacksPage from './pages/runningbacks.jsx';
import _defensePage from './pages/defense.jsx';
import _defensesPage from './pages/defenses.jsx';
import _specialTeamsPage from './pages/specialteams.jsx';
import _SpecialTeamPage from './pages/specialteam.jsx';
import _tightendPage from './pages/tightend.jsx';
import _tightendsPage from './pages/tightends.jsx';
import _widereceiverPage from './pages/widereceiver.jsx';
import _widereceiversPage from './pages/widereceivers.jsx';
import _notFoundPage from './pages/notFound.jsx';


import './index.css'

const router = createBrowserRouter([{
  path: '/',
  element: <AnalyticsNow />,
  errorElement: <_notFoundPage />
  },
  {
    path: '/quarterbacks',
    element: <_quarterbacksPage />

  },
  {
    path: '/quarterbacks/:quarterbackId',
    element: <_quarterbackPage />,
  },
  {
    path: '/runningbacks',
    element: <_runningbacksPage />

  },
  {
    path: '/runningbacks/:runningbackId',
    element: <_runningbackPage />,
  },
  {
    path: '/defenses',
    element: <_defensesPage />

  },
  {
    path: '/defenses/:defenseId',
    element: <_defensePage />,
  },
  {
    path: '/specialteams',
    element: <_specialTeamsPage />

  },
  {
    path: '/specialteams/:specialteamId',
    element: <_SpecialTeamPage />,
  },
  {
    path: '/tightends',
    element: <_tightendsPage />

  },
  {
    path: '/tightends/:tightendId',
    element: <_tightendPage />,
  },
  {
    path: '/widereceivers',
    element: <_widereceiversPage />

  },
  {
    path: '/widereceivers/:widereceiverId',
    element: <_widereceiverPage />,
  },

]);

ReactDOM.createRoot(document.getElementById('root')).render(
  <React.StrictMode>
    <RouterProvider router = {router} />
  </React.StrictMode>,
)

Код работал без ошибок, когда отображалась одна карта:

import { Link } from "react-router-dom";
import _navbar from "../NavBar/navbar";
import styles from './card.module.css';


export default function _quarterbacksPage() {

     const options = {
        method: 'GET',
           headers: {
             'x-rapidapi-key': 'secretkey',
             'x-rapidapi-host': 'nfl-api-data.p.rapidapi.com'
            }
       };
     const [img, setImg] = useState();
     const [name, setName] = useState();
    
        
     const imageUrl = "https://nfl-api-data.p.rapidapi.com/nfl-ath-img?id=3139477";
            const fetchImage = async () => {
            fetch(imageUrl, options)
            .then(response => response.json())
            .then(response => {
                const data = response.image.href;
                new Blob([data], {type: 'image/png' });  
                setImg(data);
                
            })
          };
    
    
            const FullNameUrl = 'https://nfl-api-data.p.rapidapi.com/nfl-ath-fullinfo?id=3139477';
            const fetchFullName = async () => {
                fetch(FullNameUrl, options)
                .then(response => response.json())
                .then(response => {
                    const data = response.athlete.fullName;
                    setName(data);
                
                })
            };
    
        useEffect(() => {
            fetchImage();
            fetchFullName();
        }, []);


    return (
        <>
            <div>
                <_navbar />
                
                <img className = {styles.cardImage} src = {img} alt = "profile picture"></img>
                <h2 className = {styles.cardTitle}>{name</h2>
                                                      
            </div>
        </>
    );
}

Насколько я вижу, оператор return действительно не находится внутри функции. Определение function _quarterbacksPage() полностью завершается последней закрывающей скобкой } двумя строками над оператором return.

John Gordon 04.08.2024 03:04

Вы вызываете функцию useState(), не определяя ее и не импортируя откуда-либо. Так что да, ошибка выглядит разумной. Что именно вы ожидали от этой функции?

John Gordon 04.08.2024 04:00

Что ж, когда я впервые создавал эту программу, она работала, когда я отображал только одного человека. Но теперь, когда я пытаюсь отобразить список людей, это больше не работает. Я пытаюсь вернуть список игроков со своими карточками. @Джон Гордон

Jace Johnson 04.08.2024 04:10

Хорошо, но вы не ответили на мой вопрос. Ваш код ссылается на функцию useState(), но эта функция нигде не определена и не импортирована. Так какой же вы ОЖИДАЛИ эту функцию?

John Gordon 04.08.2024 05:12

@Джон Гордон, я проведу еще несколько исследований по useState() и сделаю еще один пост. Я относительно новичок в мире реагирования, поэтому учусь, работая над этим проектом.

Jace Johnson 04.08.2024 18:26
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
2
5
60
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я вижу проблему в вашем коде: вы не импортировали useState в файл. То же самое и с useEffect. Любой крючок, который вы используете, должен быть импортирован сверху следующим образом:

import { useState, useEffect } from 'react';

Другая серьезная проблема заключается в том, что вы используете перехватчик React внутри цикла. В документации React говорится, что хуки следует использовать в верхней части компонента, и хуки можно вызывать из функций React (а не из обычных функций JavaScript).

Вы можете обратиться к документации React по правилам хуков, чтобы найти все правила, связанные с хуками: https://react.dev/reference/rules#rules-of-hooks

В вашем случае вы также можете обратиться к этой части документации. Там конкретно сказано, что не используйте хуки внутри условий, функций JavaScript и циклов: https://react.dev/reference/rules/rules-of-hooks#only-call-hooks-from-react-functions

Решение вашей проблемы:

Ваш код работает с одной картой. Вы можете создать новый компонент с именем _quarterbacksPages в той же папке, где находится _quarterbacksPage. Затем объявите квотербеков и составьте карту квотербеков. Импортируйте компонент _quarterbacksPage сверху и передайте защитника компоненту следующим образом: Новый компонент с именем _quarterbacksPages:

import React from 'react';
import _quarterbacksPage from './_quarterbacksPage';
    
export default function _quarterbacksPages() {
const quarterbacks = [3139477, 4241479, 3918298, 3915511, 2577417];

return (
 <>
   {
     quarterbacks.map((qb) => (
       <_quarterbacksPage key = {qb} quarterback = {qb} />
     ))
   }
 </>
 )
}

Измененный компонент _quarterbacksPage:

Ваш код для компонента _quarterbacksPage идеален. Просто внесите в это небольшие изменения. Получите идентификатор из реквизита компонента, который вы используете для imageUrl и FullNameUrl.

export default function _quarterbacksPage({ quarterback }) {
// code inside function is same that you wrote for single card
}

Здесь защитник — это тот идентификатор, который вы используете в URL. Мы передали это из родительского компонента _quarterbacksPages.

Теперь просто измените URL-адреса в компоненте _quarterbacksPage следующим образом:

// for imageUrl
const imageUrl = `https://nfl-api-data.p.rapidapi.com/nfl-ath-img?id=${quarterback}`;
// for FullNameUrl
const FullNameUrl = `https://nfl-api-data.p.rapidapi.com/nfl-ath-fullinfo?id=${quarterback}`;

Теперь единственное, что ожидается, — это то, что вы используете _quarterbacksPage внутри createBrowserRouter. Вместо этого используйте _quarterbacksPages. Ваш код будет работать отлично.

Другие вопросы по теме