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”组件会处理渲染自身所需的所有操作。
添加回答
举报