【问题标题】:Multiple if/else in JSXJSX 中的多个 if/else
【发布时间】:2020-01-29 12:39:17
【问题描述】:

我正在尝试在 jsx 中增加 map() 中的变量并隐藏基于它的元素。我收到以下错误

编译失败。
解析错误:相邻的 JSX 元素必须包含在封闭标记中。你想要一个 JSX 片段 ...?

我认为这是困扰我的行

{myIncrement % 2 == 0 && <div data-key-id={row.key} key={row.key} className="">}

有什么想法吗? (我不是一个全职的 React 开发者,所以有点迷失在 jsx 中)

这是该部分的完整代码

{props.config.map(row => (
  (row.isRequired || props.data[row.key]) && 
     <React.Fragment>
        {row.isFullWidth ? 
          <div data-key-id={row.key} key={row.key} className="">
            <div className="">
              <div className="">some key</div>
                <div className="">some value</div>
            </div>
          </div>
         :
          <React.Fragment>
            {myIncrement % 2 == 0 && <div data-key-id={row.key} key={row.key} className="">}
              <div className="">
                <div className="">{row.key}:</div>
                <div className="">{row.value}</div>
              </div>
            {myIncrement % 2 == 0 && </div>}

            {myIncrement = !row.isFullWidth ? myIncrement + 1 : myIncrement}
          </React.Fragment>
         }
      </React.Fragment>
))}

【问题讨论】:

  • 可以添加周边代码吗?您收到的错误表明您在组件中返回了多个 JSX 元素,这是不允许的,它们应该用单个组件包装
  • ` {myIncrement % 2 == 0 &&
    }
    {row.key}:
    {row.value}
    {myIncrement % 2 == 0 &&
    } ` 您不能分离开始和闭合标签。它们必须一起退回
  • @dbramwell 该错误与此代码隔离,它是myIncrement % 2 === 0 代码确实导致了错误,我只是不知道如何解决它。

标签: javascript reactjs jsx


【解决方案1】:

第一个问题:地图周围缺少碎片

基本上你不能有一个看起来像的 jsx

<foo/>
<bar/>

因为 React 不知道根元素,它需要做 React 魔术,将 JSX 转换为响应式 HTML,所以你需要有

<>
  <foo/>
  <bar/>
</>

&lt;&gt;&lt;React.Fragment&gt; 的简写

这就是有关相邻元素的错误消息的含义。您的地图将创建相邻元素:

['a', 'b', 'c'].map(letter => <div>{letter}</div>)

will produce

<div>a</div>
<div>b</div>
<div>c</div>

要修复此错误,只需在地图周围添加一个片段:

<>
  { props.config.map(row => (
    /* ... */
  )}
</>

第二个问题:无效的 JSX 语法

这是无效的 JSX:

{ myIncrement % 2 == 0 && <div data-key-id={row.key} key={row.key} className=""> }
  <div className="">
    <div className="">{row.key}:</div>
    <div className="">{row.value}</div>
  </div>
{myIncrement % 2 == 0 && </div>}

我知道它在编写时有意义,但它不会编译,因为 React 会尝试分别评估 myIncrement % 2 == 0 &amp;&amp; &lt;div data-key-id={row.key} key={row.key} className=""&gt;myIncrement % 2 == 0 &amp;&amp; &lt;/div&gt; 并且这是不可能的(还没有?)。

你可以得到类似的东西如下:

// define this part of the component somewhere
const Foo = ({ key, value}) => (
  <div>
    <div>{key}:</div>
    <div>{value}</div>
  </div>
);

// surround it or not by a div, depending on the increment value
{ myIncrement % 2 == 0 ? (
    <div data-key-id={row.key} key={row.key}>
      <Foo key={row.key} value={row.value}/>
    </div>
  ) : (
    <Foo key={row.key} value={row.value}/>
  )
}

【讨论】:

  • 不,问题发生在第二个React.Fragment
  • map 之间不需要片段,因为它返回一个数组,并且数组可以在 JSX 中渲染。那部分很好。
  • 这也不是正确的答案。我仍然需要将第二个内容放在包装器内。但我看到我的第一个陈述存在问题,但这就是我必须做的事情才能让它发挥作用。我想我必须在 JSX 之外解决它并自己连接字符串。
【解决方案2】:

你不能做什么:

  <React.Fragment>
    {myIncrement % 2 == 0 && <div data-key-id={row.key} key={row.key} className="">} // <= opening tag
      <div className="">
        <div className="">{row.key}:</div>
        <div className="">{row.value}</div>
      </div>
    {myIncrement % 2 == 0 && </div>} // <= Enclosing tag

    {myIncrement = !row.isFullWidth ? myIncrement + 1 : myIncrement}
  </React.Fragment>

它被拒绝了,因为你试图渲染一个&lt;div&gt; 开始标记,而不是在其他语句中的&lt;/div&gt; 标记。 它们必须像这样属于一起:

  <React.Fragment>
    {myIncrement % 2 == 0 ? (
      <div data-key-id={row.key} key={row.key} className="">
        <div className=""> // <= could be a new component 
          <div className="">{row.key}:</div>
          <div className="">{row.value}</div>
        </div>
      </div>
    )
    : (
      <div className=""> // <= could be a new component
        <div className="">{row.key}:</div>
        <div className="">{row.value}</div>
      </div>
    )
  }

    {myIncrement = !row.isFullWidth ? myIncrement + 1 : myIncrement}
  </React.Fragment>

【讨论】:

  • 我在这个答案中看到的唯一问题是您没有提供“其他”案例。我认为如果 confition 已满,他想将这些 div 包装在外部的 div 中,但如果没有,则显示没有包装器的内部内容。
  • 当然,如果条件不完整,他正在谈论隐藏元素,但我认为他试图隐藏包装,而不是内容。无论哪种方式,他都不会犯那个错误,因为我们可以看到他知道如何显示(或不显示)元素。
  • 是的,我并没有试图隐藏内容,只有包装器 if 语句被满足。
  • 我明白了。已更新。
  • 这还是不行。我需要将内容放在包装器内。所以基本上一个包装器中有两个“元素”。
猜你喜欢
  • 2018-01-25
  • 2020-01-27
  • 2017-10-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-15
  • 2021-07-17
相关资源
最近更新 更多