【问题标题】:What are the advantages or disadvantages of putting our items in an empty div in React?在 React 中将我们的项目放在一个空的 div 中的优点或缺点是什么?
【发布时间】:2021-03-28 00:45:44
【问题描述】:

在编写经典 html 时,我们通常将元素放在一个 div 中,并给这个 div 一个类名或 id。 但是在 react 中,我们将元素放在一个空的 div 中。我们不会同时为这个 div 提供 id 和类名。

造成这种情况的主要原因是什么?你能解释一下吗?

我的代码示例如下。

空 div 代码示例

`

import classes from '../Input/Input.module.css';


const LoginPage = () => {
  return (

    <div>
      <div className={classes['login-page']} >
        <form>
          <h1 className={classes['login-header']} >Login</h1>
          <div className={classes.block}>
            <label>Email:</label>
            <input type="email"
              className={classes['classes-inputs']} />
          </div>
          <div className={classes.block}>
            <label>Password:</label>
            <input type="password"
              className={classes['classes-inputs']}
            />
          </div>
          <div className={classes.block}>
            <input type="submit" value="Login" />
          </div>
        </form>
      </div>
    </div>

  )
}


export default LoginPage;

`

非空 div 代码示例

`

import classes from '../Input/Input.module.css';


const LoginPage = () => {
  return (

    <div className={classes['login-page']} >
      <form>
        <h1 className={classes['login-header']} >Login</h1>
        <div className={classes.block}>
          <label>Email:</label>
          <input type="email"
            className={classes['classes-inputs']} />
        </div>
        <div className={classes.block}>
          <label>Password:</label>
          <input type="password"
            className={classes['classes-inputs']}
          />
        </div>
        <div className={classes.block}>
          <input type="submit" value="Login" />
        </div>
      </form>
    </div>

  )
}


export default LoginPage;

`

【问题讨论】:

    标签: html reactjs


    【解决方案1】:

    实际上,您不必这样做。 唯一的限制是您必须返回单个元素,因此在您没有包装器的情况下,您可以放置​​一个空的 div。 如果你不想有一个空的 div,你可以使用片段 &lt;&gt;&lt;/&gt; 来包装你的元素

    【讨论】:

      【解决方案2】:

      我认为这里的问题是 JSX 解析器。

      JSX 和 React 只能返回一个组件,所以我们不能做下面这样的事情

      return (
        <ComponentA />
        <ComponentB />
        <ComponentC />
      )
      

      您必须为所有这些都放置一个最外层的包装器,并且大多数时候我们使用&lt;div&gt;标签

      return (
        <div>
          <ComponentA />
          <ComponentB />
          <ComponentC />
        </div>
      )
      

      但您可以使用React.Fragment 或其快捷方式&lt;&gt; 作为开始标签,使用&lt;/&gt; 作为结束标签。

      return (
        <> // Can replace with <React.Fragment>
          <ComponentA />
          <ComponentB />
          <ComponentC />
        </> // Can replace with </React.Fragment>
      )
      

      使用&lt;div&gt;React.Fragment 有一些不同。你可以在这里阅读Why are Fragments in React 16 better than container divs?

      【讨论】:

        【解决方案3】:

        在大多数情况下,包装器 div 是“无关紧要的”,只是因为 React 组件要求您只返回一个元素而被添加。这种行为会导致无用的标记,有时甚至会导致渲染无效的 HTML,这很糟糕。

        例如,我们可以有一个组件 Table 来呈现 HTML 表格,并且在该表格内,列与另一个名为 Columns 的组件一起呈现。它可能看起来像这样。

        `

        class Table extends React.Component {
          render() {
            return (
              <table>
                <tr>
                  <Columns />
                </tr>
              </table>
            );
          }
        }
        class Columns extends React.Component {
          render() {
            return (
              <div>
                <td>Hello</td>
                <td>World</td>
              </div>
            );
          }
        }
        

        `

        这将导致呈现无效的 HTML,因为 Columns 组件中的包装器 div 呈现在 .

        `

        <table>
          <tr>
            <div>
              <td>Hello</td>
              <td>World</td>
            </div>
          </tr>
        </table>
        

        `

        React Fragments 允许您对子列表进行分组,而无需向 DOM 添加额外的节点,因为 Fragment 不会呈现到 DOM。所以基本上我们使用 React.Fragment,而我们通常会使用包装器 div。

        我们可以使用带有 语法的片段。所以我们可以如下编写 Columns 组件。

        `

        class Columns extends React.Component {
          render() {
            return (
              <React.Fragment>
                <td>Hello</td>
                <td>World</td>
              </React.Fragment>
            );
          }
        }
        

        `

        【讨论】:

        • 你也可以使用 ....> 代替 ....
        • 是的,这是一个简单易用的示例,感谢您的贡献。
        【解决方案4】:

        不需要这样做。如果您认为 JSX 只是 React.createElement(...) 的函数,您可以完全使用函数内部的函数 (hof) 来构建您在 JSX 中构建的树。

        例子:

        return React.createElement('div',{
          children: React.createElement('div',{
            className: classes['login-page'],
            children: React.createElement(/* and so on */)
          })
        })
        

        您可以立即看到您可以在 div 的第二级开始“创建”树。您还可以看到为什么以下不可能与其他答案类似:

        return (
          React.createElement('div',{})
          React.createElement('div',{})
          React.createElement('div',{})
        )
        

        不,您不需要返回单个元素。您可以将有效的 javascript 包装成:

        return [
          React.createElement('div',{ key: 'some_id_1' }),
          React.createElement('div',{ key: 'some_id_2' }),
          React.createElement('div',{ key: 'some_id_3' })
        ]
        

        这就是为什么您应该将所有内容包装到片段&lt;&gt;&lt;/&gt;、数组或单个包装器组件/jsx-tag 中的原因。注意关键属性——React 可以用它做一些优化魔法。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2011-02-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-12-04
          相关资源
          最近更新 更多