这里是沙箱链接:https://codesandbox.io/s/playvideo-e3dbw
我使用video.js在react项目中显示视频,并将其导入到我的<VideoPlayer/>组件中。
现在我想用react-loadable来包装<VideoPlayer/>,因为video.js太大了。
但是当我访问我正在运行的项目中的实际视频播放器时,该项目崩溃了,并且我在浏览器的控制台中收到了一些错误消息:
react-dom.development.js:57 Uncaught Invariant Violation: Element type is
invalid: expected a string (for built-in components) or a class/function (for
composite components) but got: object.
Check the render method of `LoadableComponent`.Warning: Can't perform a React state update on an unmounted component. This is
a no-op, but it indicates a memory leak in your application. To fix, cancel
all subscriptions and asynchronous tasks in the componentWillUnmount method.以下是我的一些源代码片段。问题发生在我使用react-loadable包装<VideoPlayer/>组件之后,如下所示:
const LoadableVideoPlayer = Loadable({
loader: () => import('./VideoPlayer'),
render(loaded, props) {
let Component = loaded.default;
return <Component {...props}/>;
},
loading: <div>Loading...</div>
});我想根据当前状态在页面中渲染pdf播放器或视频播放器。下面是<LoadableVideoPlayer/>组件的用法:
if (this.state.currentPlayer==='Video' && videoSrc) {
return <LoadableVideoPlayer key={videoSrc} videoSrc={videoSrc}/>
} else if (this.state.currentPlayer==='PDF' && pdfSrc) {
return <PDFPlayer key={pdfSrc} pdfSrc={pdfSrc}/>
}
}这是我的<VideoPlayer/>组件:
import React from 'react';
import videojs from 'video.js';
import 'video.js/dist/video-js.css';
class VideoPlayer extends React.Component {
componentDidMount() {
const src = this.props.videoSrc;
const videoPlayerOptions = {
controls: true,
sources:[
{
src:src,
type:'video/mp4'
}
]
};
this.player = videojs(this.videoNode, videoPlayerOptions, () => {
console.log("Ready to play")
})
}
componentWillUnmount() {
// if (this.player) {
// this.player.dispose()
// }
}
render() {
return(
<div data-vjs-player style={{width:'100%'}}>
<video ref={node => this.videoNode = node} className="video-js" />
</div>
)
}
}
export default VideoPlayer请注意,在componentWillUnmount()方法中,我注释掉了这些代码行,因为如果没有注释掉,即使我不使用react-loadable,也会收到另一条错误消息。
我认为问题可能出在这里,但我搜索了很多次,都没有找到任何解决方案。
要了解更多细节,这里是我导入并使用它的地方。
import React from 'react';
import Loadable from 'react-loadable';
import PDFPlayer from './PDFPlayer';
const LoadableVideoPlayer = Loadable({
loader: () => import('./VideoPlayer'),
render(loaded, props) {
let Component = loaded.default;
return <Component {...props}/>;
},
loading: <div>Loading...</div>
});
class ResourcePlayer extends React.Component {
state = {currentPlayer:'PDF'};
onPlayerChange = selectedPlayer => {
this.setState({currentPlayer:selectedPlayer})
};
renderPlayer = () => {
const {videoSrc, pdfSrc} = this.props;
if (this.state.currentPlayer==='Video' && videoSrc) {
return <LoadableVideoPlayerkey={videoSrc} videoSrc={videoSrc}/>
} else if (this.state.currentPlayer==='PDF' && pdfSrc) {
return <PDFPlayer key={pdfSrc} pdfSrc={pdfSrc}/>
} else {
return (
<div>
{/*Some placeholder here, not important for this problem*/}
</div>
)
}
};
render () {
// suppose here are some logic to switch the state between 'PDF' and 'Video'
return (
{this.renderPlayer()}
)
}
}发布于 2019-08-08 19:59:44
我想我已经找到原因了。我应该使用react组件来加载属性,而不是在LoadableVideoPlayer组件旁边使用<div>Loading...</div>。
const LoadableComponent = () => {
return <div>Loading...</div>
};
const LoadableVideoPlayer = Loadable({
loader: () => import('./VideoPlayer'),
render(loaded, props) {
let Component = loaded.default;
return <Component {...props}/>;
},
loading: LoadableComponent
});另外,我错过了一些错误消息,对此我深表歉意。以下是指示此问题的错误消息:
Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: <div />. Did you accidentally export a JSX literal instead of a component?
in LoadableComponent (created by ResourcePlayer)
in div (created by ResourcePlayer)
in ResourcePlayerhttps://stackoverflow.com/questions/57406874
复制相似问题