如何在不重新渲染 ReactJS 中的特定组件的情况下更新 CSS 网格?

How to update a CSS Grid without re-rendering a specific component in ReactJS?

我正在 React 网站上工作,该网站有一个视频播放器,它应该在所有路线上连续播放。我正在尝试找出一种使用 CSS Grid 构建特定动态布局的方法,该布局将更新自身以及除视频组件之外的所有组件的状态。

主要挑战是确保视频组件不会重新呈现以避免播放中断。

主页(初始)布局如下:

// Code from an online generator
<div class="container">
  <div class="Video"></div>
  <div class="Content"></div>
  <div class="Sidebar"></div>
</div>

.container {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  grid-template-rows: 1fr 1fr 1fr;
  gap: 0px 0px;
  grid-auto-flow: row;
  grid-template-areas:
      "Video Video Sidebar"
      "Content Content Sidebar"
      ". . .";
  }

.Video { grid-area: Video; }
.Content { grid-area: Content; }
.Sidebar { grid-area: Sidebar; }

所有其他路线布局如下:

// Code from an online generator
<div class="container">
    <div class="Content"></div>
    <div class="Video"></div>
    <div class="Sidebar"></div>
</div>

.container {  display: grid;
    grid-template-columns: 1fr 1fr 1fr;
    grid-template-rows: 1fr 1fr 1fr;
    gap: 0px 0px;
    grid-auto-flow: row;
    grid-template-areas:
        "Content Content Video"
        "Content Content Sidebar"
        ". . .";
}

.Content { grid-area: Content; }
.Video { grid-area: Video; }
.Sidebar { grid-area: Sidebar; }

是否可以使用 CSS 网格从布局 1 过渡到布局 2 而无需重新渲染视频组件?

我设法通过在 Switch 之外创建视频 Component 1 的布局并将其余组件作为布局的 {children} 传递来实现它。

我为每个组件、每个布局创建了两个不同的 grid-area CSS 属性版本,并使用它们根据设计将组件放置在网格单元中。

最后,我用useLocation()获取了当前路由,并在grid-area类.

之间有条件地切换
/* CSS */
.parent {
  display: grid;
  grid-template-columns: repeat(12, 1fr);
  grid-column-gap: 20px;
  grid-auto-rows: minmax(100px, auto) minmax(max-content, 2fr);
}

.video {
  grid-area: 1 / 1 / 9 / 10;
}

.sidebar {
  grid-area: 1 / 10 / 13 / 13;
}

.content {
  grid-area: 9 / 1 / 13 / 10;
}

.video-alt {
  grid-area: 1 / 10 / 1 / 13;
}

.sidebar-alt {
  grid-area: 2 / 10 / 13 / 13;
}

.content-alt {
  grid-area: 1 / 1 / 13 / 10;
}

// JSX
export const isHome = () => {
    let location = useLocation();
    return location.pathname === "/";
}

<div className="container mx-auto">
    <Header />
    <div className='parent'>
        <Stream />
        {isHome() ? <Chat /> : null}
        <div className={isHome() ? "content" : "content-alt"}  >
            {children}
        </div>
    </div>
    <Footer/>
</div>


// <Stream />
<div className={!isHome() ? "video-alt sticky top-20 z-40" : "video"}>
    <div ref={ref} className="">
        <VideoJS options={videoJsOptions} onReady={handlePlayerReady}/>
   </div>
   <div className="mt-4">{!isHome() ? <Chat /> : null}</div>
</div>