从 api 获取数据并创建对象后渲染卡片
Render Cards after fetch data from api and create an object
我正在尝试学习 ReactJS..
今天我试图创建一个包含获取结果的对象数组,然后创建卡片,但我只能更新状态,但卡片不会重新渲染。你能帮我吗?
App.js
const teamsForLoop = [
Team1,
Team2,
Team3
];
const [allPlayers, setAllPlayers] = useState([]);
const [team, setTeam] = useState([]);
const [allTeams] = useState(teamsForLoop);
const [loading, setLoading] = useState(true);
useEffect(() => {
const playerInfo = async() => {
setLoading(true)
allTeams.map(async(teamArray) => {
setTeam([])
teamArray.map(async (player) => {
let playerName = player.split(" ");
const result = await axios.get(
`https://www.thesportsdb.com/api/v1/json/2/searchplayers.php?p=${playerName[0]}%20${playerName[1]}`
);
if (result.data.player === null) {
setTeam((state) => {
return [...state];
});
} else {
setTeam((state) => {
return [...state, result.data.player[0]];
});
}
});
setAllPlayers(team);
});
setLoading(false);
};
playerInfo();
},[]);
if (loading) return "...Loading...";
return (
<>
<PlayerList allPlayers={allPlayers} />
</>
);
}
export default App;
PlayerList.js
function PlayerList({ allPlayers }) {
const myData = []
.concat(allPlayers)
.sort((a, b) => (a.idTeam !== b.idTeam ? 1 : -1))
return (
<div>
{myData.map((player,index) =>
(
<div key={index}>
...........
</div>
)
)}
</div>
);
}
我认为我的问题出在 useEffect 挂钩上,或者可能出在我的 fetch 函数上。
我已经使用数组但没有状态完成了它。
问题
我现在看到的问题是,您试图在循环中缓存处于 team
状态的抓取玩家,然后使用 team
状态更新 players
状态.这里的问题是 React 状态更新是异步处理的,所以调用 setAllPlayers(team);
时 team
还没有更新。
解决方案
将 allTeams
数组映射到 GET 请求,等待它们解析,然后将单个 allPlayers
状态更新加入队列会更简单。展平团队球员的阵列并将它们映射到 axios GET Promise。等待这些解决并将结果映射到玩家数组。
示例:
function App() {
const [allPlayers, setAllPlayers] = useState([]);
const [allTeams] = useState(teamsForLoop);
const [loading, setLoading] = useState(true);
const playerInfo = async () => {
setLoading(true);
const response = await Promise.all(
allTeams
.flat()
.map((player) =>
axios.get(
`https://www.thesportsdb.com/api/v1/json/2/searchplayers.php?p=${player}`
)
)
);
const players = response.map((result) => result.data.player[0]);
setAllPlayers(players);
setLoading(false);
};
useEffect(() => {
playerInfo();
}, []);
if (loading) return "...Loading...";
return <PlayerList allPlayers={allPlayers} />;
}
我正在尝试学习 ReactJS.. 今天我试图创建一个包含获取结果的对象数组,然后创建卡片,但我只能更新状态,但卡片不会重新渲染。你能帮我吗?
App.js
const teamsForLoop = [
Team1,
Team2,
Team3
];
const [allPlayers, setAllPlayers] = useState([]);
const [team, setTeam] = useState([]);
const [allTeams] = useState(teamsForLoop);
const [loading, setLoading] = useState(true);
useEffect(() => {
const playerInfo = async() => {
setLoading(true)
allTeams.map(async(teamArray) => {
setTeam([])
teamArray.map(async (player) => {
let playerName = player.split(" ");
const result = await axios.get(
`https://www.thesportsdb.com/api/v1/json/2/searchplayers.php?p=${playerName[0]}%20${playerName[1]}`
);
if (result.data.player === null) {
setTeam((state) => {
return [...state];
});
} else {
setTeam((state) => {
return [...state, result.data.player[0]];
});
}
});
setAllPlayers(team);
});
setLoading(false);
};
playerInfo();
},[]);
if (loading) return "...Loading...";
return (
<>
<PlayerList allPlayers={allPlayers} />
</>
);
}
export default App;
PlayerList.js
function PlayerList({ allPlayers }) {
const myData = []
.concat(allPlayers)
.sort((a, b) => (a.idTeam !== b.idTeam ? 1 : -1))
return (
<div>
{myData.map((player,index) =>
(
<div key={index}>
...........
</div>
)
)}
</div>
);
}
我认为我的问题出在 useEffect 挂钩上,或者可能出在我的 fetch 函数上。 我已经使用数组但没有状态完成了它。
问题
我现在看到的问题是,您试图在循环中缓存处于 team
状态的抓取玩家,然后使用 team
状态更新 players
状态.这里的问题是 React 状态更新是异步处理的,所以调用 setAllPlayers(team);
时 team
还没有更新。
解决方案
将 allTeams
数组映射到 GET 请求,等待它们解析,然后将单个 allPlayers
状态更新加入队列会更简单。展平团队球员的阵列并将它们映射到 axios GET Promise。等待这些解决并将结果映射到玩家数组。
示例:
function App() {
const [allPlayers, setAllPlayers] = useState([]);
const [allTeams] = useState(teamsForLoop);
const [loading, setLoading] = useState(true);
const playerInfo = async () => {
setLoading(true);
const response = await Promise.all(
allTeams
.flat()
.map((player) =>
axios.get(
`https://www.thesportsdb.com/api/v1/json/2/searchplayers.php?p=${player}`
)
)
);
const players = response.map((result) => result.data.player[0]);
setAllPlayers(players);
setLoading(false);
};
useEffect(() => {
playerInfo();
}, []);
if (loading) return "...Loading...";
return <PlayerList allPlayers={allPlayers} />;
}