简体   繁体   English

Map循环中的条件语句

[英]Conditional Statement Within Map Loop

In ReactJS, I am trying to call an if statement within a map loop. 在ReactJS中,我试图在map循环中调用if语句。 An example code is this: 示例代码是这样的:

var items = ['abc', '123', 'doe', 'rae', 'me'];
return (
  <div>

       {items.map((item, index) => (
            <span dangerouslySetInnerHTML={{ __html: item }}></span>

            {index % 2:
                <h1>Test Output/h1>
            }

        ))}

  </div>
}

Except I keep getting his error: 除了我不断收到他的错误:

 Module build failed: SyntaxError: Unexpected token, expected , (73:11)
web_1  | 
web_1  |   71 |                     <span dangerouslySetInnerHTML={{ __html: item }}></span>
web_1  |   72 |                     
web_1  | > 73 |                     {index % 2:
web_1  |      |                     ^

How can I call an if statement within a loop? 如何在循环中调用if语句?

First, you can't return multiple sibling elements as JSX without a parent container, unless you put them into an array (though you can't return arrays from render methods until React adds support for returning fragments). 首先,没有父容器,您不能将多个兄弟元素作为JSX返回,除非您将它们放入数组中(尽管您不能从render方法返回数组,直到React添加对返回片段的支持为止)。

This is invalid: 这是无效的:

return (
  <div>First sibling</div>
  <div>Second sibling</div>
);

These are both valid: 这些都是有效的:

return (
  <div>
      <div>First sibling</div>
      <div>Second sibling</div>
  <div>
);

// vs.
// (notice this requires adding keys)

return ([
  <div key={1}>First sibling</div>,
  <div key={2}>Second sibling</div>
]);

Second, if you want to use a conditional statement to render components, you have to do it like this: 其次,如果要使用条件语句来呈现组件,则必须这样做:

{(index % 2 === 0) &&
  <div>This will render when index % 2 === 0</div>
}

The reason this works is that the && operator in JavaScript evaluates to the second operand (your JSX in this case) if the first operand is truthy. 这样做的原因是,如果第一个操作数为真,则JavaScript中的&&运算符将得出第二个操作数(在本例中为JSX)。 You can also use ternary statements, like this: 您还可以使用三元语句,如下所示:

{(index % 2 === 0) ?
  <div>This will render when index % 2 === 0</div>
:
  <div>This will render when index % 2 !== 0</div>
}


Putting this all together 全部放在一起

var items = ['abc', '123', 'doe', 'rae', 'me'];
return (
  <div>

       {items.map((item, index) => (
            <div>
                <span dangerouslySetInnerHTML={{ __html: item }}></span>

                {(index % 2 === 0) &&
                    <h1>Test Output/h1>
                }
            </div>

        ))}

  </div>
}


[Edit] Important note [编辑]重要说明

I should mention that whenever you're rendering an array of elements using something like items.map(...) , you should really be assigning a unique key to each element in the list that you're rendering: 我应该提到的是,每当使用items.map(...)类的元素来渲染元素数组时,您实际上应该为要渲染的列表中的每个元素分配一个唯一键:

{items.map((item, index) => (
  <div key={item.get('id')}>Item #{index}</div>
))}

The reason is that React does some optimizations here to make rendering (and re-rendering) lists less costly. 原因是React在这里进行了一些优化,以降低渲染(和重新渲染)列表的成本。 If it sees a list that used to be composed of keys 0, 1, 2 and you've done some operation to reorder the items in your state, so that now the keys are passed to your map function in the order 0, 2, 1 , it won't rebuild the DOM to reflect the changed order, but rather will just swap the DOM nodes (which is faster). 如果它看到一个曾经由键0, 1, 2组成的列表,并且您已经完成了一些操作以对状态中的项进行重新排序,那么现在这些键将以0, 2, 1的顺序传递给地图函数。 0, 2, 1 ,它不会重建DOM来反映更改后的顺序,而只是交换DOM节点(速度更快)。

This leads to why you don't want to use index as a key for your elements, UNLESS you know that their order won't change. 这导致了为什么您不想使用index作为元素的键,除非您知道它们的顺序不会改变。 Let's say you used the iteration index as your keys: 假设您使用迭代索引作为键:

{items.map((item, index) => (
  <div key={index}>Item #{index}</div>
))}

Now, if your items change order, they'll be output with the keys in the same order (index 0 will always be the first index, index 1 will always be the second index, and so on) but with different text inside each div. 现在,如果您的项目更改顺序,则它们的键输出顺序相同(索引0将始终是第一个索引,索引1将始终是第二个索引,依此类推),但每个div内的文本不同。 React will do a diff with the real DOM, notice that the value of each div has changed, and rebuild that entire chunk of the DOM from scratch. React将对真实的DOM进行比较,注意每个div的值已更改,然后从头开始重建DOM的整个块。

This gets even worse if your list elements include something with state that isn't reflected in the DOM, like an <input> . 如果您的列表元素包含状态未在DOM中反映的内容(例如<input> ,则情况将更加糟糕。 In that case, React will rebuild the DOM, but any text the user has input in those fields will remain exactly where it was! 在这种情况下,React将重建DOM,但是用户在这些字段中输入的任何文本将保持原样! Here's an example from Robin Pokorny that demonstrates what can go wrong (sourced from this article ): 这是Robin Pokorny的示例,演示了可能出问题的地方(摘自本文 ):

https://jsbin.com/wohima/edit?js,output https://jsbin.com/wohima/edit?js,output

I guess your condition for the if is index % 2 == 1 which shows the Heading when index is an odd number 我猜您的条件是if index % 2 == 1 ,它在index奇数时显示标题

{index % 2 == 1 && (
     <h1>Test Output/h1>
)}

Official Documentation 官方文件

But in your case, you are writing this if condition within {}. 但就您而言,您正在{}中编写if条件。 That means, you are now writing the JavaScript. 这意味着您正在编写JavaScript。 So, just use the JavaScript syntax. 因此,只需使用JavaScript语法。

if(index % 2 == 1){
   return(
    <div>
      <span dangerouslySetInnerHTML={{ __html: item }}></span>
      <h1>Test Output/h1>
    </div>);
}

Update: As Jaromanda pointed out, you need to return one element. 更新:正如Jaromanda指出的那样,您需要返回一个元素。 So, wrapping your <span> and <h1> into <div> will gives a single element. 因此,将<span><h1>包装到<div>中将得到一个元素。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM