我试图传递数据到组件,我从API接收。我正在使用'createAsyncThunk'保存它的状态,而不是当试图获得我的数据,得到错误“未定义”。我理解它的发生,因为它需要一些时间来从API获得数据,但我如何才能迫使组件“等待”?我的代码有什么问题?
下面是我的代码:
第一步:从API中获取数据,过滤后推送到状态中。
import { generateRandom } from "../helpers/randomInt";
const API_URL = "https://akabab.github.io/superhero-api/api/all.json";
export const fetchHeroes = createAsyncThunk(
"data_slice/fetchHeroes",
async function (_, { rejectWithValue }) {
try {
const res = await fetch(API_URL);
if (!res.ok) {
throw new Error("Could not fetch cart data!");
}
const data = await res.json();
const marvel_heroes = data.filter(
(item) => item.biography.publisher == "Marvel Comics"
);
const dark_horse_heroes = data.filter(
(item) => item.biography.publisher == "Dark Horse Comics"
);
const dc_heroes = data.filter(
(item) => item.biography.publisher == "DC Comics"
);
const filtered_data = [
...marvel_heroes,
...dark_horse_heroes,
...dc_heroes,
];
const heroesData = [];
for (let index = 0; index < 49; index++) {
const item = filtered_data[generateRandom(0, 439)];
heroesData.push(item);
}
const main_data = [filtered_data, heroesData];
return main_data;
} catch (error) {
return rejectWithValue(error.message);
}
}
);
const heroesSlice = createSlice({
name: "data_slice",
initialState: { heroes_data: [], isLoading: null, error: null },
extraReducers: {
[fetchHeroes.pending]: (state) => {
state.isLoading = true;
},
[fetchHeroes.fulfilled]: (state, action) => {
state.heroes_data = action.payload;
state.isLoading = false;
},
[fetchHeroes.rejected]: (state) => {
state.isLoading = false;
state.error = "Something go wrong!";
alert("aaa");
},
},
});
export default heroesSlice;
第2步:在“App.js”中使用“UseEffect”触发(使用调度)获取函数“fetchHeroes”,以便在应用程序启动时获取数据
import { Fragment, useState, useEffect } from "react";
import { useSelector, useDispatch } from "react-redux";
import { fetchHeroes } from "./store/heroes-slice";
import { Routes, Route } from "react-router-dom";
import Main from "./pages/Main";
import Heroes from "./pages/Heroes";
import Hero_page from "./pages/Hero_page";
import LoginModal from "./components/LoginModal";
import RegisterModal from "./components/RegisterModal";
function App() {
const [scrollY, setScrollY] = useState(0);
const isLoginModal = useSelector((state) => state.modal.isLoginModal);
const isRegisterModal = useSelector((state) => state.modal.isRegisterModal);
const dispatch = useDispatch();
function logit() {
setScrollY(window.scrollY);
console.log(new Date().getTime());
}
useEffect(() => {
function watchScroll() {
window.addEventListener("scroll", logit);
}
watchScroll();
return () => {
window.removeEventListener("scroll", logit);
};
});
useEffect(() => {
dispatch(fetchHeroes());
}, [dispatch]);
return (
<Fragment>
{isRegisterModal && <RegisterModal></RegisterModal>}
{isLoginModal && <LoginModal></LoginModal>}
<Routes>
<Route path="/" element={<Main />} />
<Route path="/heroes" exact element={<Heroes scroll={scrollY} />} />
<Route path="/heroes/:heroId" element={<Hero_page />}></Route>
</Routes>
</Fragment>
);
}
export default App;
第3步:我尝试使用“usSelect”从state(heros_fetched_data)接收数据,但在尝试通过“map”解析数据时,出现错误“undefined”
import classes from "./Heroes.module.css";
import Header from "../components/Header";
import Footer from "../components/Footer.js";
import Hero_card from "../components/Hero_card";
import { useSelector } from "react-redux";
import { Link } from "react-router-dom";
export default function Heroes(props) {
const heroes_fetched_data = useSelector((state) => state.heroes.heroes_data);
const loadingStatus = useSelector((state) => state.heroes.isLoading);
console.log(heroes_fetched_data);
const heroes_cards = heroes_fetched_data[1].map((item, i) => (
<Link to={`/heroes/${item.id}`} key={item.id + Math.random()}>
<Hero_card
key={i}
img={item.images.lg}
name={item.name}
publisher={item.biography.publisher}
/>
</Link>
));
return (
<div className={classes.main}>
<Header scroll={props.scroll} />
{!loadingStatus && (
<section className={classes.heroes}>
<ul className={classes.ully} id="heroes">
{heroes_cards}
</ul>
</section>
)}
{loadingStatus && <p>Loading...</p>}
<Footer />
</div>
);
}
1条答案
按热度按时间im9ewurl1#
因为提取是异步的,所以不能假定
Heroes
组件中的heroes_fetched_data
在组件第一次呈现时就有数据。在尝试使用之前,需要检查该数据是否存在。如果还没有,组件应该呈现一个备用的“正在加载”状态。当提取完成时,组件应该自动重新呈现,此时heroes_fetched_data
将具有您需要的数据,您可以继续。大致上,您需要类似于以下伪代码的代码: