3 回答

TA貢獻1783條經驗 獲得超4個贊
您不應該在組件主體中產生副作用,您應該使用useEffect副作用來產生副作用,因此您不應該創建組件async,而是可以將函數定義為異步,使用它們useEffect然后設置狀態。
function Leagues({ country }) {
const [countryData, setCountryData] = React.useState([]);
React.useEffect(() => {
async function getCountries() {
const url = `https://www.thesportsdb.com/api/v1/json/1/search_all_leagues.php?c=${country}&s=Soccer`;
const res = await fetch(url);
const { countrys } = await res.json();
setCountryData(countrys);
}
getCountries();
}, [country]);
return (
<div>
<ul>
{countryData.map((country, i) => {
return <li key={i}>{country.strLeague}</li>;
})}
</ul>
</div>
);
}
ReactDOM.render(
<Leagues country="Spain" />,
document.getelementById("root")
);
由于async代碼片段中不支持函數,因此這里是帶有.thenPromise 鏈的工作版本。
function Leagues({ country }) {
const [countryData, setCountryData] = React.useState([]);
React.useEffect(() => {
const url = `https://www.thesportsdb.com/api/v1/json/1/search_all_leagues.php?c=${country}&s=Soccer`;
fetch(url)
.then((res) => res.json())
.then(({ countrys }) => setCountryData(countrys));
}, [country]);
return (
<div>
<ul>
{countryData.map((country, i) => {
return <li key={i}>{country.strLeague}</li>;
})}
</ul>
</div>
);
}
ReactDOM.render(
<Leagues country="Spain" />,
document.getElementById("root")
);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.1/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.1/umd/react-dom.production.min.js"></script>
<div id="root" />

TA貢獻1895條經驗 獲得超7個贊
這是組件,只需在應用程序中調用它,<Leagues c='Spain'/> 我調用參數c,因為country顯然在countrys任何地方都不可讀。
import React, { useEffect, useState } from "react";
const Leagues = ({c}) => {
const [countrys, countrysSet] = useState(false);
useEffect(() => {
countrysSet(false);
const url = `https://www.thesportsdb.com/api/v1/json/1/search_all_leagues.php?c=${c}&s=Soccer`;
fetch(url).then( res => res.json()).then(countrysSet);
}, [c]);
if( countrys === false ) {
return <p>loading...</p>;
}
return (
<div>
<ul>
{countrys.map((country, i) => {
return <li key={i}>{country.strLeague}</li>;
})}
</ul>
</div>
);
};
export default Leagues;

TA貢獻1812條經驗 獲得超5個贊
我認為你應該將該代碼分解為幾個部分。另外,您不能在函數體內進行 api 調用,否則每次重新渲染組件時它都會運行。讓我用你的例子向你展示:
import React, { useEffect, useState } from "react";
const GetLeagues = async (country) => {
// This helper function fetches your leagues
const url = 'your url'
const res = await fetch(url);
const { countries } = await res.json();
return countries;
};
const Leagues = () => {
const [leagues, setLeagues] = useState([]);
useEffect(() => {
async function init() {
// Declaring an extra function as useEffect
// cannot be async.
const countries = await GetLeagues();
setLeagues(countries);
}
init();
}, []);
return (
<div>
{leagues.map((country, i) => {
return <li key={i}>{country.strLeague}</li>;
})}
</div>
);
};
export default Leagues;
請注意,現在“GetLeagues”只是一個實用函數,而不是 React 組件。這樣就可以重復使用而不渲染任何東西。
此外,您的“Leagues”組件會處理渲染自身所需的所有操作。
添加回答
舉報