如何在不重新渲染 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>
我正在 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>