Компилятор инструментов разработчика в настоящее время выдает мне эту ошибку:
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>
</>
);
}
Вы вызываете функцию useState()
, не определяя ее и не импортируя откуда-либо. Так что да, ошибка выглядит разумной. Что именно вы ожидали от этой функции?
Что ж, когда я впервые создавал эту программу, она работала, когда я отображал только одного человека. Но теперь, когда я пытаюсь отобразить список людей, это больше не работает. Я пытаюсь вернуть список игроков со своими карточками. @Джон Гордон
Хорошо, но вы не ответили на мой вопрос. Ваш код ссылается на функцию useState()
, но эта функция нигде не определена и не импортирована. Так какой же вы ОЖИДАЛИ эту функцию?
@Джон Гордон, я проведу еще несколько исследований по useState()
и сделаю еще один пост. Я относительно новичок в мире реагирования, поэтому учусь, работая над этим проектом.
Я вижу проблему в вашем коде: вы не импортировали 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. Ваш код будет работать отлично.
Насколько я вижу, оператор return действительно не находится внутри функции. Определение
function _quarterbacksPage()
полностью завершается последней закрывающей скобкой}
двумя строками над оператором return.