在 React 中渲染组件时,如何将一个 axios 请求的输出用作另一个请求的依赖项?
How do I use the output of one axios request as a dependency for another when rendering components in React?
我已经为此苦苦挣扎了一段时间,我不确定如何解决这个问题。
基本上,我正在尝试将一些组件渲染到我的索引页面上,这是我的代码如下:
App.js
import Index from "./Components/Index"
import axios from "axios"
export default function App() {
const [movieList, setMovieList] = React.useState([])
let featured = []
let coming = []
let showing = []
React.useEffect(() => {
console.log("Ran App Effects")
axios.get(`API_CALL_TO_GET_LIST_OF_MOVIES`)
.then(res =>{
setMovieList(res.data)
})
}, [])
return(
<div>
{movieList.map(movie =>{
if(movie.status === 'featured'){
featured.push(movie.api_ID)
} else if (movie.status === 'upcoming'){
coming.push(movie.api_ID)
} else{
showing.push(movie.api_ID)
}
})}
<Index featured={featured} coming={coming} showing={showing}/>
</div>
)
}
在上面的代码中,我收到了一个对象数组,并根据它们的状态将它们放入一些空数组中,并将它们作为道具发送到我的索引组件中。
这是我的索引组件的样子:
import React from "react"
import Header from "./Header"
import Footer from "./Footer"
import MovieCard from "./MovieCard"
import axios from "axios"
export default function Index(props) {
const [featuredMovies, setFeaturedMovies] = React.useState([])
const [comingMovies, setComingMovies] = React.useState([])
//const featured = [419704,338762,495764,38700,454626,475557]
//const coming = [400160,514847,556678,508439,524047,572751]
React.useEffect(() => {
console.log("Ran Effect")
axios.all(props.featured.map(l => axios.get(`API_CALL_TO_GET_SPECIFIC_MOVIE/${l}`)))
.then(axios.spread(function (...res){
setFeaturedMovies(res)
}))
.catch((err) => console.log(err))
axios.all(props.coming.map(l => axios.get(`API_CALL_TO_GET_SPECIFIC_MOVIE/${l}`)))
.then(axios.spread(function (...res){
setComingMovies(res)
}))
.catch((err) => console.log(err))
}, [])
return(
<body>
<Header />
<section className="home">
<div className="container">
<div className="row">
<div className="col-12">
<a className="home__title">FEATURED MOVIES</a>
</div>
{ featuredMovies.map(movie =>{
return <MovieCard movie={movie} featured={true} />
}) }
{console.log(props.featured)}
</div>
</div>
</section>
<section className="home">
<div className="container">
<div className="row">
<div className="col-12">
<a className="home__title">COMING SOON</a>
</div>
{ comingMovies.map(movie =>{
return <MovieCard movie={movie} featured={false} />
})}
</div>
</div>
</section>
<Footer/>
</body>
)
}
我 运行 遇到的问题是,每当我第一次 运行 应用程序时,它都能正常工作,但是当我点击刷新按钮时,组件不再呈现
它唯一一次在我刷新页面时重新呈现是在我取消注释时,
//const featured = [419704,338762,495764,38700,454626,475557]
//const coming = [400160,514847,556678,508439,524047,572751]
并将 props.featured.map
和 props.coming.map
替换为 featured.map
和 coming.map
,因此使用硬编码值而不是从 props 传入的值。
任何帮助都将不胜感激,因为我完全被卡住了,目前正在拔头发。
我冒昧地修改了你的代码。在下面的示例中,我借助 useMemo
并通过检查每部电影的状态 属性 将数据重新排列为三组。将任何与数据相关的逻辑 放在呈现逻辑之外 很重要。
我还移动了您的一些 HTML 结构。您正在 <div>
内输出一个 <body>
标签。外层应该控制外部 HTML 结构,所以我将 HTML 移动到 App
组件。
import { useState, useEffect, useMemo } from 'react'
import Header from "./Components/Header"
import Footer from "./Components/Footer"
import Index from "./Components/Index"
import axios from "axios"
export default function App() {
const [movieList, setMovieList] = useState([])
const featuredMovies = useMemo(() => {
return movieList.filter(({ status }) => status === 'featured');
}, [movieList]);
const upcomingMovies = useMemo(() => {
return movieList.filter(({ status }) => status === 'upcoming');
}, [movieList]);
const showingMovies = useMemo(() => {
return movieList.filter(({ status }) => status !== 'featured' && status !== 'upcoming');
}, [movieList]);
useEffect(() => {
axios.get(`API_CALL_TO_GET_LIST_OF_MOVIES`)
.then(res =>{
setMovieList(res.data)
})
}, [])
return (
<body>
<Header />
<Index data={featuredMovies} title="Featured Movies" featured={true} />
<Index data={upcomingMovies} title="Coming Soon" />
<Index data={showingMovies} title="Showing Now" />
<Footer/>
</body>
)
}
由于我们现在有三组电影(精选、即将上映和播放),因此使用三个组件来处理这些数据集而不是让一个组件处理多个数据集也很有意义。每个 Index
组件都有自己的数据集和其他道具来渲染其中的电影。
import MovieCard from "./MovieCard"
export default function Index({ data, title, featured = false }) {
return (
<section className="home">
<div className="container">
<div className="row">
<div className="col-12">
<a className="home__title">{title}</a>
</div>
{data.map(movie => {
return <MovieCard movie={movie} featured={featured} />
})}
</div>
</div>
</section>
);
}
我已经为此苦苦挣扎了一段时间,我不确定如何解决这个问题。
基本上,我正在尝试将一些组件渲染到我的索引页面上,这是我的代码如下:
App.js
import Index from "./Components/Index"
import axios from "axios"
export default function App() {
const [movieList, setMovieList] = React.useState([])
let featured = []
let coming = []
let showing = []
React.useEffect(() => {
console.log("Ran App Effects")
axios.get(`API_CALL_TO_GET_LIST_OF_MOVIES`)
.then(res =>{
setMovieList(res.data)
})
}, [])
return(
<div>
{movieList.map(movie =>{
if(movie.status === 'featured'){
featured.push(movie.api_ID)
} else if (movie.status === 'upcoming'){
coming.push(movie.api_ID)
} else{
showing.push(movie.api_ID)
}
})}
<Index featured={featured} coming={coming} showing={showing}/>
</div>
)
}
在上面的代码中,我收到了一个对象数组,并根据它们的状态将它们放入一些空数组中,并将它们作为道具发送到我的索引组件中。 这是我的索引组件的样子:
import React from "react"
import Header from "./Header"
import Footer from "./Footer"
import MovieCard from "./MovieCard"
import axios from "axios"
export default function Index(props) {
const [featuredMovies, setFeaturedMovies] = React.useState([])
const [comingMovies, setComingMovies] = React.useState([])
//const featured = [419704,338762,495764,38700,454626,475557]
//const coming = [400160,514847,556678,508439,524047,572751]
React.useEffect(() => {
console.log("Ran Effect")
axios.all(props.featured.map(l => axios.get(`API_CALL_TO_GET_SPECIFIC_MOVIE/${l}`)))
.then(axios.spread(function (...res){
setFeaturedMovies(res)
}))
.catch((err) => console.log(err))
axios.all(props.coming.map(l => axios.get(`API_CALL_TO_GET_SPECIFIC_MOVIE/${l}`)))
.then(axios.spread(function (...res){
setComingMovies(res)
}))
.catch((err) => console.log(err))
}, [])
return(
<body>
<Header />
<section className="home">
<div className="container">
<div className="row">
<div className="col-12">
<a className="home__title">FEATURED MOVIES</a>
</div>
{ featuredMovies.map(movie =>{
return <MovieCard movie={movie} featured={true} />
}) }
{console.log(props.featured)}
</div>
</div>
</section>
<section className="home">
<div className="container">
<div className="row">
<div className="col-12">
<a className="home__title">COMING SOON</a>
</div>
{ comingMovies.map(movie =>{
return <MovieCard movie={movie} featured={false} />
})}
</div>
</div>
</section>
<Footer/>
</body>
)
}
我 运行 遇到的问题是,每当我第一次 运行 应用程序时,它都能正常工作,但是当我点击刷新按钮时,组件不再呈现
它唯一一次在我刷新页面时重新呈现是在我取消注释时,
//const featured = [419704,338762,495764,38700,454626,475557]
//const coming = [400160,514847,556678,508439,524047,572751]
并将 props.featured.map
和 props.coming.map
替换为 featured.map
和 coming.map
,因此使用硬编码值而不是从 props 传入的值。
任何帮助都将不胜感激,因为我完全被卡住了,目前正在拔头发。
我冒昧地修改了你的代码。在下面的示例中,我借助 useMemo
并通过检查每部电影的状态 属性 将数据重新排列为三组。将任何与数据相关的逻辑 放在呈现逻辑之外 很重要。
我还移动了您的一些 HTML 结构。您正在 <div>
内输出一个 <body>
标签。外层应该控制外部 HTML 结构,所以我将 HTML 移动到 App
组件。
import { useState, useEffect, useMemo } from 'react'
import Header from "./Components/Header"
import Footer from "./Components/Footer"
import Index from "./Components/Index"
import axios from "axios"
export default function App() {
const [movieList, setMovieList] = useState([])
const featuredMovies = useMemo(() => {
return movieList.filter(({ status }) => status === 'featured');
}, [movieList]);
const upcomingMovies = useMemo(() => {
return movieList.filter(({ status }) => status === 'upcoming');
}, [movieList]);
const showingMovies = useMemo(() => {
return movieList.filter(({ status }) => status !== 'featured' && status !== 'upcoming');
}, [movieList]);
useEffect(() => {
axios.get(`API_CALL_TO_GET_LIST_OF_MOVIES`)
.then(res =>{
setMovieList(res.data)
})
}, [])
return (
<body>
<Header />
<Index data={featuredMovies} title="Featured Movies" featured={true} />
<Index data={upcomingMovies} title="Coming Soon" />
<Index data={showingMovies} title="Showing Now" />
<Footer/>
</body>
)
}
由于我们现在有三组电影(精选、即将上映和播放),因此使用三个组件来处理这些数据集而不是让一个组件处理多个数据集也很有意义。每个 Index
组件都有自己的数据集和其他道具来渲染其中的电影。
import MovieCard from "./MovieCard"
export default function Index({ data, title, featured = false }) {
return (
<section className="home">
<div className="container">
<div className="row">
<div className="col-12">
<a className="home__title">{title}</a>
</div>
{data.map(movie => {
return <MovieCard movie={movie} featured={featured} />
})}
</div>
</div>
</section>
);
}