嗨,我试图在我的网站上实现直播视频,因为我已经使用了节点媒体服务器,我在这里面临的问题是我的网站陷入无限的重新渲染,因为我已经创建了一个播放器的功能。对于这个问题,有没有什么特别的解决方案?我正在分享一段足以理解这个问题的代码。
const videoRef = useRef();
const {id } = props.match.params;
useEffect(() => {
props.fetchStream(id);
buildPlay();
}, [buildPlay]);
function buildPlay() {
if(player || !props.stream){
return ;
}
var player = flv.createPlayer({
type: 'flv',
url: `http://localhost:8000/live/${id}.flv`
});
player.attachMediaElement(videoRef.current);
player.load();
}
if(!props.stream){
return <div>Loading...</div>
}
return (
<div>
<video ref={videoRef} style={{width: "100%"}} controls/>
<h1>{props.stream.title}</h1>
<h5>{props.stream.description}</h5>
</div>
)发布于 2021-05-14 16:39:28
导致无限重渲染的原因是,在组件函数体中声明的所有内容都会在每次渲染时重新声明,因此buildPlay在每次渲染时都是一个新函数,并且效果将无限执行。将函数指定为依赖项并不常见(也许props.callback除外),但如果您确实需要它,则应该将该函数移出组件并将其参数化(请参阅下面的show code snippet & run )。
看看buildPlay,在这种情况下,实际发生变化并应该被指定为依赖项的是[props.match.params.id, props.stream, videoRef.current]。您的效果代码应如下所示:
const dependencies = [props.match.params.id, props.stream, videoRef.current];
useEffect(() => {
if (!props.stream || !videoRef.current) return;
// either defined outside of component, parameterized as buildPlay(id, stream, elem)
buildPlay(...dependencies);
// or inlined in the effect
/* if(player || !props.stream){
return ;
}
var player = flv.createPlayer({
type: 'flv',
url: `http://localhost:8000/live/${id}.flv`
});
player.attachMediaElement(videoRef.current);
player.load(); */
}, dependencies);请看下面代码片段中的两个React应用程序:第一个应用程序采用您的方法,第二个应用程序将依赖函数移出组件并对其进行参数化。
const InfiniteRenderApp = () => {
const [runCount, setRunCount] = React.useState(0);
function doSomething() {
if (runCount < 10000) {
setRunCount(runCount + 1);
} else {
throw 'Infinite render loop. stop here!';
}
}
React.useEffect(() => {
try {
doSomething();
} catch (err) {
setRunCount(err);
}
}, [doSomething]);
return <strong>{runCount}</strong>;
};
ReactDOM.render(<InfiniteRenderApp/>, document.getElementById('infinite-render-app'));
function doSomething(runCount, setRunCount) {
setRunCount(runCount + 1);
}
const GoodApp = () => {
const [runCount, setRunCount] = React.useState(0);
React.useEffect(() => {
doSomething(runCount, setRunCount);
}, [doSomething]);
return <strong>{runCount}</strong>;
};
ReactDOM.render(<GoodApp/>, document.getElementById('app'));<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.8.0/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.8.0/umd/react-dom.production.min.js"></script>
<div id="infinite-render-app"></div>
<div id="app"></div>
https://stackoverflow.com/questions/67530968
复制相似问题