You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Grid与styled-components无法正确渲染React五分屏组件

问题描述

我之前已经学会在父容器使用display: flex、子元素使用flex: 1实现二分屏组件。现在尝试通过display: grid构建一个五分屏组件:左侧侧边栏占据第一列及两行空间,其余四个组件分别占据一列一行。目前已能渲染出网格结构,但仅第一行第一列能显示内容,其余区域无文本展示。我使用了React Router与styled-components,相关代码及截图如下:

五分屏渲染截图

相关代码

App.js

import React from "react";
import { Routes, Route } from "react-router-dom";
import styled, { createGlobalStyle } from "styled-components";
import {NoMatch} from "./pages/NoMatch";
import {Dashboard} from "./pages/Dashboard";
import {About} from "./pages/About";
import {Home} from "./pages/Home";
import { LayoutNavigation } from "./components/LayoutNavigation";


export default function App() {
  return (
    <>
      <Routes>
        <Route path="/" element={<LayoutNavigation />}>
          <Route index element={<Home />} />
          <Route path="about" element={<About />} />
          <Route path="dashboard" element={<Dashboard />} />
          <Route path="*" element={<NoMatch />} />
        </Route>
      </Routes>
    </>
  );
}

Home.js

import { SplitScreenQuad } from "../components/SplitScreen";
import styled from "styled-components";

const Sidebar = () => {
  return (
    <div>
      <h1 style={{ backgroundColor: "lightblue" }}>Sidebar</h1>
    </div>
  );
};

const UserInputFields = () => {
  <div>
    <h1 style={{ backgroundColor: "lightgreen" }}>UserInputFields</h1>;
  </div>;
};

const UserData = () => {
  <div>
    <h1 style={{ backgroundColor: "lightgreen" }}>UserData</h1>;
  </div>;
};

const TableResults = () => {
  <div>
    <h1 style={{ backgroundColor: "pink" }}>TableResults</h1>;
  </div>;
};

const ImageResults = () => {
  <div>
    <h1 style={{ backgroundColor: "yellow" }}>ImageResults</h1>;
  </div>;
};

export const Home = () => {
  return (
    <>
      <h1>HOME</h1>
      <SplitScreenQuad
        sidebar={Sidebar}
        topleft={UserInputFields}
        topright={UserData}
        bottomleft={TableResults}
        bottomright={ImageResults}
      />
    </>
  );
};

SplitScreen.js

/*Filename: SplitScreen.js*/
import React from "react";
import styled from "styled-components";

export const SplitScreenQuad = ({
  sidebar: Sidebar,
  topleft: Topleft,
  topright: Topright,
  bottomleft: Bottomleft,
  bottomright: Bottomright,
}) => {
  return (
    <>
      <ContainerQuad>
        <PaneQuad>
          <Sidebar id="sidebar" />
        </PaneQuad>
        <PaneQuad>
          <Topleft id="topleft" />
        </PaneQuad>
        <PaneQuad>
          <Topright id="topright" />
        </PaneQuad>
        <PaneQuad>
          <Bottomleft id="bottomleft" />
        </PaneQuad>
        <PaneQuad>
          <Bottomright id="bottomright" />
        </PaneQuad>
      </ContainerQuad>
    </>
  );
};

const ContainerQuad = styled.div`
  display: grid;
  grid-template-columns: auto 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  gap: 1rem;
  background-color: lightcoral;
  #sidebar {
    grid-column: 1;
    grid-row: 1 / span 2;
  }
  #topleft {
    grid-column: 2;
    grid-row: 1;
  }
  #topright {
    grid-column: 3;
    grid-row: 1;
  }
  #bottomleft {
    grid-column: 2;
    grid-row: 2;
  }
  #bottomright {
    grid-column: 3;
    grid-row: 2;
  }
`;

const PaneQuad = styled.div``;
解决方案

问题出在Home.js里的四个子组件没有正确返回JSX内容:

  • UserInputFields、UserData、TableResults、ImageResults这几个箭头函数组件,你写了JSX但没有用return语句返回,也没有用括号直接包裹JSX(箭头函数隐式返回的语法要求)。

修改后的Home.js相关组件代码如下:

const UserInputFields = () => {
  return (
    <div>
      <h1 style={{ backgroundColor: "lightgreen" }}>UserInputFields</h1>
    </div>
  );
};

const UserData = () => (
  <div>
    <h1 style={{ backgroundColor: "lightgreen" }}>UserData</h1>
  </div>
);

const TableResults = () => (
  <div>
    <h1 style={{ backgroundColor: "pink" }}>TableResults</h1>
  </div>
);

const ImageResults = () => (
  <div>
    <h1 style={{ backgroundColor: "yellow" }}>ImageResults</h1>
  </div>
);

两种写法都可以:要么显式写return加括号,要么直接用括号包裹JSX实现箭头函数的隐式返回。

另外可以优化一下SplitScreen的网格布局写法,避免使用ID选择器,改用给PaneQuad传递props来控制网格位置,让代码更符合React组件化的思路:

// 修改SplitScreen.js
export const SplitScreenQuad = ({
  sidebar: Sidebar,
  topleft: Topleft,
  topright: Topright,
  bottomleft: Bottomleft,
  bottomright: Bottomright,
}) => {
  return (
    <ContainerQuad>
      <PaneQuad area="sidebar">
        <Sidebar />
      </PaneQuad>
      <PaneQuad area="topleft">
        <Topleft />
      </PaneQuad>
      <PaneQuad area="topright">
        <Topright />
      </PaneQuad>
      <PaneQuad area="bottomleft">
        <Bottomleft />
      </PaneQuad>
      <PaneQuad area="bottomright">
        <Bottomright />
      </PaneQuad>
    </ContainerQuad>
  );
};

const ContainerQuad = styled.div`
  display: grid;
  grid-template-columns: auto 1fr 1fr;
  grid-template-rows: 1fr 1fr;
  grid-template-areas:
    "sidebar topleft topright"
    "sidebar bottomleft bottomright";
  gap: 1rem;
  background-color: lightcoral;
`;

const PaneQuad = styled.div`
  grid-area: ${props => props.area};
`;

这种用grid-template-areas的写法可读性更强,也不需要依赖ID来定位网格项。


内容的提问来源于stack exchange,提问作者ahauser

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 03:05:49