Javascript 反应上下文不';t渲染组件
我正在使用上下文和反应路由器。当我创建上下文并包装组件时,没有呈现任何内容。当我检查控制台时,我可以看到我正在获取的记录数据(它来自Javascript 反应上下文不';t渲染组件,javascript,reactjs,react-router,react-hooks,react-context,Javascript,Reactjs,React Router,React Hooks,React Context,我正在使用上下文和反应路由器。当我创建上下文并包装组件时,没有呈现任何内容。当我检查控制台时,我可以看到我正在获取的记录数据(它来自AnimeContext中的useEffect),但标题和主页组件不会出现 我正试图在主页上显示topTv、topAiring和topComeding 这是我的建议 上下文文件 import React, { useState, useEffect, createContext } from 'react' const AnimeContext = createC
AnimeContext
中的useEffect),但标题和主页组件不会出现
我正试图在主页
上显示topTv
、topAiring
和topComeding
这是我的建议
上下文文件
import React, { useState, useEffect, createContext } from 'react'
const AnimeContext = createContext()
const API = "https://api.jikan.moe/v3"
const AnimeProvider = (props) => {
const urls = [
`${API}/top/anime/1/airing`,
`${API}/top/anime/1/tv`,
`${API}/top/anime/1/upcoming`,
]
// State for top Anime
const [topTv, setTopTv] = useState([])
const [topAiring, setTopAiring] = useState([])
const [topUpcoming, setTopUpcoming] = useState([])
// State for Anime details
const [animeReq, setAnimeReq] = useState({
fetching: false,
anime: []
})
// State for Anime search form
const [dataItems, setDataItems] = useState([])
const [animeSearched, setAnimeSearched] = useState(false)
// Fetch top Anime
const fetchTopAnime = async () => {
return Promise.all(
urls.map(async url => {
return await fetch(url); // fetch data from urls
})
)
.then((responses) => Promise.all(responses.map(resp => resp.json())) // turn data into JSON
.then(data => {
const topTvFiltered = data[0].top.filter(item => item.rank <= 5) // filter out top 6
const topAiringFiltered = data[1].top.filter(item => item.rank <= 5)
const topUpcomingFiltered = data[2].top.filter(item => item.rank <= 5)
setTopTv(topTvFiltered)
setTopAiring(topAiringFiltered)
setTopUpcoming(topUpcomingFiltered)
console.log(data)
})
)
.catch(err => console.log("There was an error:" + err))
}
useEffect(() => {
fetchTopAnime()
}, [])
// Fetch Anime details
const fetchAnimeDetails = async () => {
setAnimeReq({ fetching: true })
const response = await fetch(`${API}/${props.match.params.animeId}`)
const data = await response.json()
console.log(data);
setAnimeReq({ fetching: false, anime: data }) // set initial state to hold data from our API call
}
// Fetch searched Anime
const handleSubmit = async (e) => {
e.preventDefault()
const animeQuery = e.target.elements.anime.value
const response = await fetch(`${API}/search/anime?q=${animeQuery}&page=1`)
// const response2 = await fetch(`${API}/top/anime/1/movie`)
const animeData = await response.json()
// const topAnime = await response2.json()
setDataItems(animeData.results)
setAnimeSearched(!animeSearched)
props.history.push('dashboard')
}
const { fetching, anime } = animeReq;
return (
<AnimeContext.Provider value={{
topTv,
setTopTv,
topAiring,
setTopAiring,
topUpcoming,
setTopUpcoming,
dataItems,
setDataItems,
animeSearched,
setAnimeSearched,
fetching,
anime,
fetchTopAnime,
fetchAnimeDetails,
handleSubmit
}}>
{props.childen}
</AnimeContext.Provider>
)
}
export { AnimeProvider, AnimeContext }
所以我要么错过了一些关键的东西,要么我不理解上下文是如何工作和/或如何反应的。
AnimeContext.Consumer
小时候需要一个函数,同样,如果你正在使用useContext
,那么首先就没有必要用AnimeContext.Consumer
来包装你的组件
另外,由于提供程序传递了一个对象,那么useContext
将返回一个对象,因此需要对对象进行分解,而不是对数组进行分解
const HomePage = () => {
const { topTv, topAiring, topUpcoming } = useContext(AnimeContext)
return (
<HomeWrapper>
<TopAni>
{topTv.length > 0 ? <TopAniTitle>Top TV</TopAniTitle> : null}
{topTv.map((item, index) => (
<TopAnime
key={index}
image={item.image_url}
title={item.title}
item={item}
/>
))}
</TopAni>
...
</HomeWrapper>
}
}
const主页=()=>{
const{topTv,topAiring,topopumming}=useContext(AnimeContext)
返回(
{topTv.length>0?Top TV:null}
{topTv.map((项目,索引)=>(
))}
...
}
}
您在AnimeProvider中有一个输入错误
-它应该呈现{props.children}
而不是{props.childen}
我做了更改,但我的主页仍然是空的。根本没有渲染。另外,你是否从开关内部移动了AnimeProvider
?当我将其作为父级移动到顶部时,没有渲染任何内容。当它位于开关的正下方时,唯一渲染的是标题我不敢相信我犯了这么小的错误。我真的很感谢你的时间和帮助。
import React, { useContext } from 'react'
import styled from 'styled-components'
import { TopAnime } from './TopAnime';
import { AnimeContext } from '../../store/AnimeContext'
const HomePage = () => {
const [topTv, topAiring, topUpcoming,] = useContext(AnimeContext)
return (
<AnimeContext.Consumer>
<HomeWrapper>
<TopAni>
{topTv.length > 0 ? <TopAniTitle>Top TV</TopAniTitle> : null}
{topTv.map((item, index) => (
<TopAnime
key={index}
image={item.image_url}
title={item.title}
item={item}
/>
))}
</TopAni>
<TopAni>
{topAiring.length > 0 ? <TopAniTitle>Top Airing</TopAniTitle> : null}
{topAiring.map((item, index) => (
<TopAnime
key={index}
image={item.image_url}
title={item.title}
item={item}
/>
))}
</TopAni>
<TopAni>
{topUpcoming.length > 0 ? <TopAniTitle>Top Upcoming</TopAniTitle> : null}
{topUpcoming.map((item, index) => (
<TopAnime
key={index}
image={item.image_url}
title={item.title}
item={item}
/>
))}
</TopAni>
</HomeWrapper>
</AnimeContext.Consumer>
);
}
const HomeWrapper = styled.div`
height: 100%;
padding: 6rem 4.5rem;
color: ${props => props.theme.colors.white};
`
const TopAni = styled.div`
max-width: 1200px;
margin: 0 auto;
display: grid;
grid-gap: 1rem;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
grid-template-rows: auto;
padding: 1rem;
`
const TopAniTitle = styled.h2`
grid-column: 1 / -1;
justify-self: start;
`
export default HomePage
return (
<Router>
<ThemeProvider theme={theme}>
<AppWrapper>
<Header />
<Switch>
<AnimeProvider>
<Route path='/' exact component={HomePage} />
<Route path='/dashboard' exact component={AnimeCard} />
<Route path='/:animeId' component={AnimeDetails} />
</AnimeProvider>
</Switch>
</AppWrapper>
</ThemeProvider>
</Router>
);
const HomePage = () => {
const { topTv, topAiring, topUpcoming } = useContext(AnimeContext)
return (
<HomeWrapper>
<TopAni>
{topTv.length > 0 ? <TopAniTitle>Top TV</TopAniTitle> : null}
{topTv.map((item, index) => (
<TopAnime
key={index}
image={item.image_url}
title={item.title}
item={item}
/>
))}
</TopAni>
...
</HomeWrapper>
}
}