【问题标题】:How do you use CSS grid layouts with React effectively?你如何有效地使用带有 React 的 CSS 网格布局?
【发布时间】:2017-06-07 09:47:18
【问题描述】:

我目前正在使用 ReactJs 和 CSS 网格布局构建一个单页应用程序,用于组件的放置和样式。

但是,这两种技术并不能很好地结合在一起:CSS 网格布局只能(轻松地)应用于父容器的子元素(网格项)。但是 ReactJS 的本质意味着具有孙子组件甚至曾孙子组件的组件很常见。

举个例子:

React 组件树:App > ToDoList > ToDo Item > Details...

如果,onClick,我想将“ToDo Item”移动到“App”组件的 grid-row: 1,似乎唯一的方法是让 ToDoList 本身成为整个 App 组件的网格。这会导致页面上其他元素的布局问题。

我认为这两种方法不能很好地结合使用是对的,还是我对这两种技术的理解存在缺陷?

【问题讨论】:

  • 与你的问题无关,但如果你还没有被锁定,那么你可以看看tachyons。它能够提供基于内联媒体查询的网格并且是可嵌套的。

标签: css reactjs single-page-application


【解决方案1】:

您说得对,子网格已从 CSS 网格候选推荐 (https://github.com/w3c/csswg-drafts/issues/958) 中弃用。

希望它们会再次出现,它们似乎对简化复杂的布局非常有用。我只发现 CSS 网格在布局 React 应用程序或容器的顶层时很有用。

【讨论】:

    【解决方案2】:

    我肯定也看到过同样的问题,尽管这是一个比较老的问题,但我认为这是一个非常有趣的问题。

    在我看来,现实情况是,如果您使用组件驱动的框架来发挥其全部潜力,您就会遇到深度嵌套的组件/元素的问题。虽然没有真正的“子网格”,但请记住“任何网格区域都可以成为网格本身,通过设置 display:grid 然后定义行和列。” (https://gridbyexample.com/examples/example21/)。但是,如果你有这样的事情:

    <div class="page-wrapper">
      <section></section>
      <section></section>
      <section>
        <div class="section-item"></div>
        <div class="section-item">
          <div class="sub-section"><div>
        </div>
      </section>
     </div>
    

    并且您想使用 CSS 将 .sub-section 放在.page-wrapper 定义的网格上的其他位置,这不是您可以仅通过更改 css 来完成的事情,除非使用一些棘手的绝对或固定定位。归根结底,您实际上只能在其父项中重新排列项目。

    从臀部开始,我可能会建议在那个“新”位置有一个空组件,可以与原始“待办事项”组件通信,然后在click 上,将它从一个移动到另一个。

    不过,关于更广泛的主题,我认为应该在页面布局的每个渐进级别上决定使用什么 CSS 布局选项。仅仅因为 Grid 或 Flex 可以很好地(或不能)布局您的特定设计的大部分部分,并不意味着您必须(或应该)为您的应用程序的所有元素锁定该布局。更进一步,在每个部分中,我认为您应该根据内容以及它们的组织和显示方式来评估该特定部分的布局选项。

    例如,如果您的页面的主要内容是网格或砖石样式布局,那么无论如何,网格可能是该部分的最佳选择,但这并不意味着您需要整个页面布局的网格。 .您很可能会发现使用 flex 进行顶级布局可以获得更好的结果,并将您的网格放在这些部分之一中。

    再举一个例子,如果你用网格布局你的顶级页面部分,那个网格将控制你的菜单的显示位置,但是在那个网格部分中使用 flex 布局你的菜单项可能仍然很有意义。

    最后,为了给对话添加更广泛的背景,这实际上只是许多开发人员在使用 CSS 网格(如使用浮动创建列的 Bootstrap)时遇到的问题的另一个版本。当然,您可以嵌套引导行和列来创建子网格,但就获得出色的响应行为而言,在第一个或第二个嵌套层之后这是一个真正的挑战(取决于您有多少耐心以及您对仅使用该网格的承诺程度系统为您的布局)。

    我工作过的团队很快发现,使用引导程序的网格来处理大的部分并使用弹性来处理这些部分的大部分内部内容更容易维护 - 更不用说需要更少的标记了。随着网格现在也得到广泛支持,我希望我们会发现在网格更频繁地用于浮动和弹性曾经是唯一选择的地方方面的类似效率。

    【讨论】:

      【解决方案3】:

      您可以像这样定义一个组件,它“解开”每个子元素的外部元素:

      const Unwrap = ({ children, ...props}) => (
          <div {...props}>
              {children.reduce((acc, child) => acc.concat(child.children), [])}
          </div>
      )
      

      然后像这样使用它:

      <Unwrap>
          {rows.map(renderMyRow)}
      </Unwrap>
      

      编辑:我只是注意到这实际上并不总是有效,但我太累了,无法弄清楚在什么情况下它会失败。

      再次编辑:更好的方法可能是将一行包装在一个 div 中,并将 display 设置为 contents,如下所示:https://stackoverflow.com/a/53643295/1046221

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-03-09
        • 2016-01-28
        • 2019-05-21
        • 1970-01-01
        • 2020-05-13
        • 1970-01-01
        • 2014-06-02
        相关资源
        最近更新 更多