【问题标题】:Video player resets after window resize in responsive react web app?在响应式反应网络应用程序中调整窗口大小后视频播放器重置?
【发布时间】:2018-03-19 02:38:43
【问题描述】:

在我的响应式网络应用中调整窗口大小后,我无法让视频播放器持续播放。我正在使用 react-responsive 库来帮助解决这个问题。我有一个不同的 MediaQuery 元素处理我的外部“内容”组件中的每个窗口大小范围,该组件使用 antd 布局组件处理整个页面布局,所以我猜测正在发生的事情是组件的不同部分显示每个范围,导致每次检测到新范围时视频也会“重置”。 (当我删除媒体查询时,问题就消失了。)

如何做到这一点,以便当视频播放器当前正在播放视频(这是一个渲染 api 资源的 iframe)时,它继续通过一个窗口调整到不同的范围来播放?我猜我可以更改媒体查询范围并以某种特定方式嵌套它们,但我不知道该怎么做。

内容组件中的页面布局:

const Inside = props => (
  <Layout.Content
    style={{
      background: '#fff',
      padding: '10px 10px',
      width: props.width,
      margin: '0 auto 50px',
    }}
  >
    <main>
      <Route exact path="/" component={Home} />
      <Route path="/quicklooks" component={Quicklooks} />
      <Route path="/features" component={Features} />
      <Route path="/bombcasts" component={Bombcasts} />
    </main>
  </Layout.Content>
);

const Content = () => (
  <div>
    <XS><Inside width="100%" /></XS>
    <SM><Inside width="100%" /></SM>
    <MD><Inside width="740px" /></MD>
    <LG><Inside width="940px" /></LG>
    <XL><Inside width="1160px" /></XL>
    <XXL><Inside width="1160px" /></XXL>
  </div>
);

视频播放器:

const CurrentVideo = (props) => {
  const pubDateFormatted = Moment(props.pub_date).format('MMM. D, YYYY h:mma');

  return (
    <div style={{ background: '#000', margin: '0 auto', width: '100%' }}>
      <Row type="flex" justify="center">
        <Col xs={24} lg={8}>
          <div style={{ padding: '16px', color: '#fff' }}>
            <h2 style={{ color: '#fff' }}>{props.name}</h2>
            <p><i> Posted by {props.user} | {pubDateFormatted}</i></p>
            <p>{props.deck}</p>
          </div>
        </Col>
        <Col xs={24} lg={16} >
          <div className="intrinsic-container intrinsic-container-16x9">
            <iframe
              frameBorder={0}
              allowFullScreen
              title={props.name}
              src={props.embed_player}
            />
          </div>
        </Col>
      </Row>
    </div>
  );
};

CurrentVideo.propTypes = {
  name: PropTypes.string.isRequired,
  user: PropTypes.string.isRequired,
  pub_date: PropTypes.string.isRequired,
  deck: PropTypes.string.isRequired,
  embed_player: PropTypes.string.isRequired,
};

export default CurrentVideo;

设置为特定窗口宽度的不同媒体查询:

export const XXL = props => (
  <Responsive minWidth={1600}>
    {props.children}
  </Responsive>
);

export const XL = props => (
  <Responsive minWidth={1200} maxWidth={1599}>
    {props.children}
  </Responsive>
);

export const LG = props => (
  <Responsive minWidth={992} maxWidth={1199}>
    {props.children}
  </Responsive>
);
export const MD = props => (
  <Responsive minWidth={768} maxWidth={991}>
    {props.children}
  </Responsive>
);

export const SM = props => (
  <Responsive minWidth={576} maxWidth={767}>
    {props.children}
  </Responsive>
);

export const XS = props => (
  <Responsive maxWidth={575}>
    {props.children}
  </Responsive>
);

【问题讨论】:

    标签: reactjs responsive-design antd


    【解决方案1】:

    你应该看看React rules for reconciliation。他们说:“只要根元素有不同的类型,React 就会拆除旧树并从头开始构建新树。”

    看起来这里发生的情况是,当屏幕尺寸发生变化时,会创建一个不同类型的新组件,最终导致 CurrentVideo 被拆除和替换。

    这里不要使用 react-responsive。使用 React 设置 dom 元素,然后使用 normal CSS media queries 根据窗口大小更改显示。

    如果你真的坚持使用 react-responsive,你可以尝试在 Inside 中渲染 iframe,并传递一个 ref 参数以允许你存储对 dom 元素的引用(看看 @ 987654323@),然后将该引用向下传递给CurrentVideo

    【讨论】:

    • 谢谢!使用 css 媒体查询解决了这个问题。我想 currentVideo 组件被替换而不是重新渲染也可以解释为什么使用 shouldComponentUpdate 不起作用。
    【解决方案2】:

    如果不深入研究您的实现,我的猜测是 react-responsive 会导致 CurrentVideo 组件重新渲染。

    缓解这种情况的一种可能方法是使用shouldComponentUpdate() 方法来阻止重新渲染,然后检查组件的道具或状态是否实际发生了足够的变化,以至于需要重新渲染。有更多关于生命周期方法和shouldComponentUpdate() 的信息,特别是在React Docs

    【讨论】:

    • 哦,是的,我忘了提到我确实尝试过使用shouldComponentUpdate,如果 currentVideo 中的道具没有改变,则将其设置为返回 false。但是每个 @J 使用 css 查询。卡米安的建议似乎奏效了。不过谢谢。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-07-25
    • 1970-01-01
    • 1970-01-01
    • 2016-11-07
    • 1970-01-01
    相关资源
    最近更新 更多