next.js - 导入的动态组件卡在加载阶段:下一个 js
问题描述
我是下一个 js 的新手。在我的项目中,我需要显示 youtube 视频。我有一个 api,它为我提供了要显示其元详细信息的视频 ID。我想为每个视频创建动态页面。我正在使用 react-player 作为播放器。
这是我的代码
[videoId].tsx
import Head from 'next/head';
import { useRouter } from 'next/router'
import Layout from '../../components/layout';
import { IVideoItem } from '../../models/videos.model';
import VideoContainer from '../../components/videos-page/video-container';
import { getVideosPaths, getVideosPageTitle, getVideosPageDescription, getVideosData } from '../../services/videos-page.services';
export default function VideoPage({videoInfo} :IVideosPageProp) {
const router = useRouter()
if (router.isFallback) {
return <div>Loading...</div>
}
return(
<>
<Head>
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta charSet="utf-8" />
<title>{getVideosPageTitle(videoInfo)}</title>
<meta name="description" content={getVideosPageDescription(videoInfo)} />
<meta property="og:title" content={getVideosPageTitle(videoInfo)} key="ogtitle" />
<meta property="og:description" content={getVideosPageDescription(videoInfo)} key="ogdesc" />
</Head>
<VideoContainer data={videoInfo} />
</>
)
}
export async function getStaticPaths() {
const paths = await getVideosPaths()
//console.log('paths: ',paths);
return {
paths,
fallback: false
}
}
export async function getStaticProps({ params }:IVideosPageStaticProp) {
const {videoId} = params;
const videoInfo = await getVideosData(videoId)
return {
props: {
videoInfo
}
}
}
interface IVideosPageProp {
videoInfo: IVideoItem
}
interface IVideosPageStaticPropParams {
videoId: string
}
interface IVideosPageStaticProp {
params: IVideosPageStaticPropParams
}
视频容器.tsx
import { Row, Col } from 'react-bootstrap'
import { IVideoItem } from '../../models/videos.model';
import styles from './videos-container.module.scss';
import VideoTag from '../home/videos-block/video-tag';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { faEye, faThumbsUp, faThumbsDown } from '@fortawesome/free-solid-svg-icons';
import moment from 'moment';
import dynamic from 'next/dynamic';
const ReactPlayer = dynamic(
() => import('react-player'),
{ loading: () => <p>...</p>, ssr: false }
)
export default function VideoContainer({data} :IVideosPageProp){
const videoInfo:IVideoItem = data;
const videoTag = [{"tagName": "Foo", "tagId": 1}]
const fallBackElement = () => {
return <img src={videoInfo.default_thumbnail_url} width="100%"/>
}
return (
<div className={styles['videos-container']}>
<ReactPlayer
url={`https://youtu.be/${data.video_id}`}
controls
width = "100%"
light={true}
playing={true}
fallback={fallBackElement()}
config={{
youtube: {
playerVars: { showinfo: 1 }
}
}}
/>
<div className={styles['videos-body']}>
<div className={styles['tag-list-container']}>
{videoTag.map((tag, index) =>{
return <VideoTag videoTag={tag} key={index}/>
})}
</div>
<div className={styles['video-title']}>
{videoInfo.title}
</div>
<Row className={styles['video-numbers']}>
<Col md={2} xs={2}><FontAwesomeIcon icon={faEye} className={styles['views-icon']} />{videoInfo.views_count}</Col>
<Col md={2} xs={4}>{moment(new Date(videoInfo.published_at)).format('Do MMMM YYYY')}</Col>
<Col md={4} xs={2}></Col>
<Col md={2} xs={2}><FontAwesomeIcon icon={faThumbsUp} className={styles['views-icon']} />{videoInfo.like_count}</Col>
<Col md={2} xs={2}><FontAwesomeIcon icon={faThumbsDown} className={styles['views-icon']} />{videoInfo.dislike_count}</Col>
</Row>
<div className={styles['video-description']}>
{videoInfo.description}
</div>
</div>
</div>
)
}
interface IVideosPageProp {
data:IVideoItem
}
当我运行yarn dev
页面时,页面加载正常,视频播放器按预期呈现和工作。但是当我运行next buld
之后next start
,页面正在加载,但播放器没有加载。安装它在页面上显示“正在加载...”消息,我刷新了几次,没有运气。无法理解问题。任何人都可以帮忙吗?
更新 1:页面正在渲染视频标题、视频描述等。但动态导入的视频播放器未渲染。在视频播放器的位置,它显示“正在加载...”。
解决方案
不确定是否可以从 node_module 动态加载,如下所示:
const ReactPlayer = dynamic(
() => import('react-player'),
{ loading: () => <p>...</p>, ssr: false }
)
但是你应该能够通过react-player
首先创建一个组件来做到这一点,然后像这样动态导入它:
// create a component named Player.js
import ReactPlayer from 'react-player';
const Player = props => (<ReactPlayer {...props}/>)
export default Player;
// then dynamic import it:
const Player = dynamic(
() => import('../components/Player'),
{ ssr: false }
)
// Then use <Player> with the same props
推荐阅读
- sbt - 新 SBT 安装中的 Ivy 配置问题
- reactjs - 用 Enzyme 模拟功能组件的输入变化
- docker - 使 Docker Swarm 使用来自 Docker-Compose 的相同卷
- c++ - 使用可变参数调用模板类型作为成员函数
- node.js - NodeJS在声明Sequelize 6 Many To Many关联模型时相互导入文件
- vue.js - 元素 ui el-select 选项自动换行
- node.js - 找不到模块“oas3-tools”
- twilio - Twilio 中的 Routee 是什么?
- ios - 从 ReplayKit 屏幕捕获中排除 UI 元素
- mocking - 从 MySQLdb python 库模拟 callproc 方法时是否可以模拟某些 MySQL 过程存在