我正试图使用一个上下文来安装在主页上的所有视频,并重用它来安装在搜索页面中使用youtube API只过滤视频。这是我的背景:
import { createContext, useState, useEffect } from "react";
import { IVideo } from "../@types/video";
import axios from "axios";
import moment from "moment";
import { IContextProps, IVideoContext } from "../@types/context";
export const VideoContext = createContext<IVideoContext>({} as IVideoContext);
export const VideoData = ({ children }: IContextProps) => {
const [videos, setVideos] = useState<IVideo[]>([]); // the videos state is coming out as undefined
const [url, setUrl] = useState(``) // the url state shows the right url on a console.log
const [dependency, setDependency] = useState(``) // this state also has the right value in it
useEffect(() => {
load() // for some reason this seems to not be working
}, [dependency])
async function load() {
try {
const response = await axios.get(url) // this code works if I put the url manually here
setVideos(response.data.items)
}catch(error){
console.log(error)
}
}
function formatViewCount(viewCount: number): string {
if (viewCount >= 1000000) {
return `${(viewCount / 1000000).toFixed(0)} mi de visualizações`;
} else if (viewCount >= 1000) {
return `${(viewCount / 1000).toFixed(0)} mil visualizações`;
} else {
return `${viewCount} visualizações`;
}
}
function getPublishedTime(publishedAt: string) {
const now = moment();
const publishedTime = moment(publishedAt);
const diffDays = now.diff(publishedTime, 'days');
if (diffDays <= 0) {
return 'hoje';
} else if (diffDays === 1) {
return 'há 1 dia';
} else if (diffDays <= 7) {
return `há ${diffDays} dias`;
} else if (diffDays <= 30) {
const diffWeeks = Math.floor(diffDays / 7);
if (diffWeeks === 1) {
return 'há 1 semana';
} else {
return `há ${diffWeeks} semanas`;
}
} else if (diffDays <= 365) {
const diffMonths = Math.floor(diffDays / 30);
if (diffMonths === 1) {
return 'há 1 mês';
} else {
return `há ${diffMonths} meses`;
}
} else {
const diffYears = Math.floor(diffDays / 365);
if (diffYears === 1) {
return 'há 1 ano';
} else {
return `há ${diffYears} anos`;
}
}
}
return (
<VideoContext.Provider value={{ videos, getPublishedTime, formatViewCount, setUrl, setDependency }}>
{children}
</VideoContext.Provider>
)
}
字符串
这是我的主页代码:
import { useContext, useEffect } from "react";
import VideoComponent from "../../components/videoComponent";
import { Container } from "./styles";
import { VideoContext } from "../../context/videoContext";
import { IVideo } from "../../@types/video";
import { useCategoryContext } from "../../context/categoriesContext";
function Home(){
const {categoryId} = useCategoryContext()
const { videos, setUrl, setDependency } = useContext(VideoContext)
const API_KEY = 'AIzaSyBgyeOAGzLblKVCjEI-soVVLkQdNfvApkA'
useEffect(() => {
setUrl(`https://youtube.googleapis.com/youtube/v3/videos?part=snippet&part=statistics&chart=mostPopular&maxResults=48&videoCategoryId=${categoryId}&key=${API_KEY}`);
setDependency(categoryId)
}, [])
return (
<Container>
{videos.map((video: IVideo) => (
<VideoComponent video={video} key={video.id} />
))}
</Container>
)
}
export default Home;
型
这个想法是,当home组件挂载时,它将url设置为从API获取视频的上下文。试图使其工作的原因,我想使用相同的过程中,在搜索页面与不同的网址,而无需重复所有的代码。
有了这个代码,我在视频状态下得到一个身份不明的物体。
import { useContext } from "react";
import { IVideos } from "../../@types/video";
import { ChannelImage, Container, ImageBanner, TextCard, TextContainer, Title, TitleContainer } from "./styles";
import { VideoContext } from "../../context/videoContext";
function VideoComponent({video}:IVideos){
const { formatViewCount, getPublishedTime } = useContext(VideoContext)
return (
<Container>
<ImageBanner src={video.snippet.thumbnails.maxres?.url || video.snippet.thumbnails.high?.url} />
<TitleContainer>
<ChannelImage>{video.snippet.channelTitle.charAt(0).toUpperCase()}</ChannelImage>
<TextContainer>
<Title>{video.snippet.title}</Title>
<TextCard>{video.snippet.channelTitle}</TextCard>
<TextCard>{`${formatViewCount(Number(video.statistics.viewCount))} - ${getPublishedTime(video.snippet.publishedAt)}`}</TextCard>
</TextContainer>
</TitleContainer>
</Container>
)
}
export default VideoComponent;
型
这是视频卡被安装在主页以防万一(它的工作正常时,所有的代码在上下文是在主页,而不试图通过国家设置的网址)
请帮我找出错误在哪里。
1条答案
按热度按时间km0tfn4u1#
我一直在寻找,直到我找到了答案:
How to wait for setState in useEffect until render?
刚刚在主页上做了一个条件链接(将videos.map改为videos?.map)。
axios只是没有等待上下文中的setUrl。
很抱歉,我的问题写得不好。