axios 如何在组件挂载时更改上下文中的URL?

7gcisfzg  于 2023-08-04  发布在  iOS
关注(0)|答案(1)|浏览(99)

我正试图使用一个上下文来安装在主页上的所有视频,并重用它来安装在搜索页面中使用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;


这是视频卡被安装在主页以防万一(它的工作正常时,所有的代码在上下文是在主页,而不试图通过国家设置的网址)
请帮我找出错误在哪里。

km0tfn4u

km0tfn4u1#

我一直在寻找,直到我找到了答案:
How to wait for setState in useEffect until render?
刚刚在主页上做了一个条件链接(将videos.map改为videos?.map)。
axios只是没有等待上下文中的setUrl。
很抱歉,我的问题写得不好。

相关问题