【问题标题】:Workaround to add className to Fragment in React在 React 中将 className 添加到 Fragment 的解决方法
【发布时间】:2018-08-10 16:55:12
【问题描述】:

我正在尝试在 React 中创建一个无状态组件,其唯一目的是充当可重用的包装器。我也在使用 CSS 模块,因为我想要完全模块化的 CSS。

问题是我不想添加不必要的元素(甚至更多<div>s),而是我想使用 React 的 Fragments。

现在,我遇到的问题是片段(至少现在)不接受类名。所以如果我试试这个:

// 在 Wrapper.js 中:

import React, { Fragment } from 'react'
import styles from './Wrapper.css'

const wrapper = (props) => (
    <Fragment className={styles.wrapper}>
        {props.children}
    </Fragment>
)

export default wrapper

在(例如)Navbar.js 中:

import React from 'react'
import styles from './Navbar.css'
import Wrapper from '../../Layout/Wrapper'

const navBar = (props) => (
    <nav className={styles.navBar}>
        <Wrapper>
            This is the site's main navigation bar.
        </Wrapper>
    </nav>
)

export default navBar

现在我当然可以使用 div 代替 Fragment,但有没有其他解决方法可以避免使用不必要的标记,我在晚上的这个时间完全不知道这些? :)

提前感谢您提供任何见解、建议、更正或任何其他形式的帮助!

【问题讨论】:

  • 为什么不使用&lt;div&gt; 而不是片段?我还没有使用片段,但据我了解,它们只是用于在 JSX 中包装一组组件,但实际上并没有在 dom 中呈现包装元素。一个 div 实际上会将元素包装在一个 div 中。如果我错了,请纠正我......
  • 如果你想要一个类名,这个类名必须应用于一个元素,不是吗?而且 Fragments 不渲染任何元素,所以你不能使用 className 。

标签: javascript reactjs css-modules react-css-modules


【解决方案1】:

片段让您可以对子列表进行分组,而无需向 DOM 添加额外的节点。 - https://reactjs.org/docs/fragments.html

Fragments 试图解决其不必要的 dom 元素,但这并不意味着 Fragments 将完全取代 div。如果您需要在此处添加 className,则很明显,您要么在这种情况下添加一个 dom 元素,要么添加另一个 div,或者将类添加到其父级。

【讨论】:

    【解决方案2】:

    使用Fragment 意味着不会向 DOM 添加额外的节点。

    如果您想将className 分配给节点,则必须使用div

    【讨论】:

      【解决方案3】:
      1. 创建一个 css 文件并将其导入您的 App.js 中
      2. 使用Class.js 创建一个高阶组件,如下所示

          import React from  'react';
          
          const withClass = (WrappedComponent, className) => {
              return props => (
                  <div className={className}>
                      <WrappedComponent {...props} />
                  </div>
              );
          };
          
          export default withClass;
      1. 也导入您的 hoc。
      2. 在您的 App.js 中编写如下内容

          <React.Fragment>
              <p>Some JSX code here</p>
          <React.Fragment>
          
          export default withClass(App, classes.App);

      我在我的 css 文件中创建了 .App 类并将其导入,以便以后可以与 classes.App 一起使用。这样,您可以应用您在 css 中创建的任何 css 类。您可以使用相同的 wrapperComponent 来包装您拥有的每个组件,只需导入它并更改组件中的导出即可。您只需选择您选择的类名并在组件的导出语句中使用它。当您使用扩展运算符(...)编写道具时。您组件中的所有道具都将传递给此 wrapperComponent。

      PS:英语不是我的母语,所以我不擅长解释,但这段代码可以解决问题。希望版主能够查看我的解释。

      【讨论】:

        【解决方案4】:

        所以Wrapper / Fragment 唯一做的就是充当nav 的子代的 CSS 包装器?

        我对 css-modules 不是很有经验,但如果我想避免只为 className 使用额外的 DOM 节点,我会使用类似这样的方法将两个 classNames 都应用于&lt;nav&gt;

        import React from 'react'
        import navStyles from './Navbar.css'
        import wrapperStyles from './Wrapper.css'
        
        const navBar = (props) => (
            <nav className={`${navStyles.navBar} ${wrapperStyles.wrapper}`}>
               This is the site's main navigation bar.
            </nav>
        )
        
        export default navBar
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多