#javascript #reactjs #typescript #next.js
Вопрос:
Вот моя проблема: я хочу показать свои репозитории github на компоненте react, но у меня ошибка: Ошибка: Объекты недопустимы как дочерние элементы React (найдено: [обещание объекта]). Если вы хотели отобразить коллекцию дочерних элементов, вместо этого используйте массив.
Вот мой код:
import styles from "../styles/index.module.scss";
import { getRepos } from "../scripts/github";
export default async function Home() {
try {
const repos = await getRepos()
const hrefelement = repos.map(repo => <><p><a href={repo.homepage as string} target="_blank" rel="noopener noreferrer">{repo.name}</a></p></>)
return (
<div className={styles.container}>
<h1>diamant.dev</h1>
<div className={styles.repos}>
{hrefelement}
</div>
</div>
)
} catch (error) {
console.log(error);
return (
<div className={styles.container}>
<h1>diamant.dev</h1>
</div>
)
}
}
и github.ts
файл:
const githubUsername = 'diamantdev'
const githubUrl = `https://api.github.com/users/${githubUsername}/repos`
export const getRepos = async () => {
const response = await fetch(githubUrl);
const repos: [Repos] = await response.json();
const sortedRepos = repos.sort()
return sortedRepos.filter((repo) => repo.name != githubUsername || !repo.archived)
}
Комментарии:
1. Вы должны сделать вызов api в крюке useEffect. И после получения ответа сохраните этот ответ в состоянии компонента и используйте это состояние для визуализации
2. Я подозреваю , что это из-за
async function Home
, и я не думаю, что ваш компонент может быть асинхронной функцией. Вместо этого я рекомендую узнать оuseEffect
useState
крючках и: reactjs.org/docs/hooks-effect.html
Ответ №1:
export default async function Home() {
Компонентов быть не может async
. Стандартный подход к загрузке данных заключается в том, чтобы иметь состояние для ваших данных, которое начинается с пустого. Вы визуализируете один раз с этими пустыми данными (либо с нулевым значением, либо с заполнителем), затем извлекаете, а затем повторно отправляете, как только у вас есть данные.
export default function Home() {
const [error, setError] = useState();
const [repos, setRepos] = useState();
useEffect(() => {
const fetch = async () => {
try {
const repos = await getRepos();
setRepos(repos);
} catch (err) {
setError(err);
}
}
fetch();
}, []);
if (error) {
return (
<div className={styles.container}>
<h1>diamant.dev</h1>
</div>
)
} else if (repos) {
return (
<div className={styles.container}>
<h1>diamant.dev</h1>
<div className={styles.repos}>
{hrefelement}
</div>
</div>
)
} else {
// still loading
return null
}
}