首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NextJS组件

NextJS组件
EN

Stack Overflow用户
提问于 2021-07-26 06:06:42
回答 4查看 459关注 0票数 3

我需要每30秒重新加载一个远程JSON。我目前在reactJS中是这样做的,但是由于迁移到NextJS,它不起作用。

问题是,下面的工作在我目前的ReactJS网站上很好,但一旦我把它移到NextJS,它就会到处打印我们的错误。

主要有以下几点

  1. fetchTimeout
  2. sessionStorage
代码语言:javascript
复制
export default function MediaControlCard(props)  {
  const fetchTimeout = (url, ms, { signal, ...options } = {}) => {
    const controller = new AbortController();
    const promise = fetch(url, { signal: controller.signal, ...options });
    if (signal) signal.addEventListener("abort", () => controller.abort());
    const timeout = setTimeout(() => controller.abort(), ms);
    return promise.finally(() => clearTimeout(timeout));
};


    const controller = new AbortController();
    const podcast = props.podcast;
    const classes = useStyles();

    var token = uuidv4();
   // alert(sessionStorage['uuid']);
    if(!sessionStorage['uuid']){
      sessionStorage.setItem("uuid",token);
    }
    if(!sessionStorage['station']){
      sessionStorage.setItem("station","DRN1");
    }

    if(!sessionStorage['live']){
      sessionStorage.setItem("live",true);
    }
    var icyStream = "https://api.drn1.com.au:9000/station/"+sessionStorage.station+"?uuid="+sessionStorage['uuid'];

    var streamurl = icyStream;//window.com_adswizz_synchro_decorateUrl(icyStream); 

    React.useEffect(() => {
    
  
    nowplaying();
    document.getElementById("player").muted = false;
  
    });
   
    if(podcast){
        alert('test');
    }

    /*if(!sessionStorage.getItem("station")){
      sessionStorage.setItem("station","DRN1");
    }*/


   
    function nowplaying(){
      // alert("hello");
      if(sessionStorage.live === true){
      document.getElementById("podcast-only").style.display='none';
      }
       fetchTimeout(`https://api.drn1.com.au:9000/nowplaying/`+sessionStorage.station+`?uuid=`+sessionStorage['uuid'], 3000, { signal: controller.signal })
       .then(res => res.json())
       .then(
         (result) => {
           //console.log("testing player"+result.data);

           
           if(sessionStorage.getItem("live") === 'true'){

              switch(result.data[0].track.songtype)
              {
                case "A":
                  AdSystem(result.data[0]);  
                break;
                case "S":
                  Song(result.data[0]);
                  document.getElementById("Now_Playing_Artist").innerHTML = result.data[0].track.artist;
                  document.getElementById("Now_Playing_Title").innerHTML = result.data[0].track.title;
                  document.getElementById("Now_Playing_Cover").style.backgroundImage = "url('"+result.data[0].track.imageurl+"')";
                break;
                default:
                  Song(result.data[0]);
                  document.getElementById("Now_Playing_Artist").innerHTML = result.data[0].track.artist;
                  document.getElementById("Now_Playing_Title").innerHTML = result.data[0].track.title;
                  document.getElementById("Now_Playing_Cover").style.backgroundImage = "url('"+result.data[0].track.imageurl+"')";
                break;
                
              }
         
              
          
            fetch(`https://itunes.apple.com/search?term=${result.data[0].track[0].artist}+${result.data[0].track[0].title}&limit=1`)
            .then(res => res.json())
            .then(
              (result) => {
                
               if(result.results[0]){
                  document.getElementById("buylink").href = result.results[0].collectionViewUrl;
                  document.getElementById("buynow").style.display = "block";
                }
                else
                {
                  document.getElementById("buynow").style.display = "none";
                }
              })
            }
          })
    
      
      .then(console.log)
      .catch(error => {
        console.error(error);
        if (error.name === "AbortError") {
            // fetch aborted either due to timeout or due to user clicking the cancel button
        } else {
            // network error or json parsing error
        }
      });
      setTimeout(function(){nowplaying()}, 10000);
    }



    return (<>
    <Card id="nowplayinginfo_card" className={classes.card}>
        <CardMedia
        id="Now_Playing_Cover"
          className={classes.cover}
          image="//tvos.adstichr.com/client/resources/images/stations/Indie/DRN1-Logo.png"
          title="Live from space album cover"
        />
        <div className={classes.details} id="adstichrNP">
          <CardContent className={classes.content} id="song">
          <Typography  variant="subtitle1">
             Now Playing
            </Typography>
            <Typography id="Now_Playing_Title" component="h6" variant="h6">
              {props.artist}
            </Typography>
            <Typography id="Now_Playing_Artist" variant="subtitle1" color="textSecondary">
               {props.song}
            </Typography>
          </CardContent>
          <div id="buynow" className={classes.buynow}>
            <a id="buylink" target="_blank" href="#Blank"><img alt="buynow" src="https://linkmaker.itunes.apple.com/assets/shared/badges/en-us/music-lrg-1c05919c6feae5d4731d4399cd656cd72e1fadc4b86d4bd7dc93cb8f3227cb40.svg"/></a>
          </div>
          <div id="podcast-only" className={classes.controls}>
          <audio id="player" className={classes.player} controls  controlsList="nodownload" autoPlay muted>
                <source src={streamurl}
                    type="audio/mpeg"
                />
            </audio> 
          </div>
        </div>
        
      </Card>
      <Card  className={classes.card} id="adbanner">
          <CardContent  className={classes.content} id="adstichr">
                  
          </CardContent>
      </Card>
    </>
    )
  }

如何使用NextJS实现这一目标。我认为我在nextjs组件中添加的任何内容都会与ReactJS一样工作--显然不是。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2021-07-26 07:32:56

您没有显示错误,但我怀疑它与next.js的服务器端呈现特性有关。

document只在浏览器上定义,因为useEffect只在浏览器上执行,所以您要在useEffect中调用nowPlaying。这是正确的事情。但是,sessionStorage (不管包是什么)也必须在浏览器上调用。

在组件呈现之前,您应该始终从useEffect内部的存储中检索数据。

票数 0
EN

Stack Overflow用户

发布于 2021-09-09 10:05:55

NextJS为您提供了服务器端呈现功能。我认为您应该使用getStaticProps,其中有一个特殊的属性名为revalidate,它将允许您在希望使用的每一个超时时提出请求。我从最新的nextjs官方文档(11.0版)中举了一个例子。

博士:https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation

代码语言:javascript
复制
function Blog({ posts }) {
  return (
    <ul>
      {posts.map((post) => (
        <li>{post.title}</li>
      ))}
    </ul>
  )
}

// This function gets called at build time on server-side.
// It may be called again, on a serverless function, if
// revalidation is enabled and a new request comes in
export async function getStaticProps() {
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  return {
    props: {
      posts,
    },
    // Next.js will attempt to re-generate the page:
    // - When a request comes in
    // - At most once every 10 seconds
    revalidate: 10, // In seconds
  }
}

export default Blog
票数 3
EN

Stack Overflow用户

发布于 2021-07-26 15:01:46

是的,使用适当的NextJS是无法实现这一点的。我正在使用useSWR库,它有一些“更新”间隔作为选项。你可以检查一下,这里。(“选项”部分)

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/68525184

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档