首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >由于React挂钩中的依赖关系数组中的函数导致无限重新呈现

由于React挂钩中的依赖关系数组中的函数导致无限重新呈现
EN

Stack Overflow用户
提问于 2021-05-14 16:02:50
回答 1查看 105关注 0票数 0

嗨,我试图在我的网站上实现直播视频,因为我已经使用了节点媒体服务器,我在这里面临的问题是我的网站陷入无限的重新渲染,因为我已经创建了一个播放器的功能。对于这个问题,有没有什么特别的解决方案?我正在分享一段足以理解这个问题的代码。

代码语言:javascript
复制
 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>
    )
EN

回答 1

Stack Overflow用户

发布于 2021-05-14 16:39:28

导致无限重渲染的原因是,在组件函数体中声明的所有内容都会在每次渲染时重新声明,因此buildPlay在每次渲染时都是一个新函数,并且效果将无限执行。将函数指定为依赖项并不常见(也许props.callback除外),但如果您确实需要它,则应该将该函数移出组件并将其参数化(请参阅下面的show code snippet & run )。

看看buildPlay,在这种情况下,实际发生变化并应该被指定为依赖项的是[props.match.params.id, props.stream, videoRef.current]。您的效果代码应如下所示:

代码语言:javascript
复制
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应用程序:第一个应用程序采用您的方法,第二个应用程序将依赖函数移出组件并对其进行参数化。

代码语言:javascript
复制
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'));
代码语言:javascript
复制
<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>

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

https://stackoverflow.com/questions/67530968

复制
相关文章

相似问题

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