【问题标题】:React bootstrap conditionally render based on map indexReact bootstrap 基于地图索引有条件地渲染
【发布时间】:2019-10-05 07:10:18
【问题描述】:

我正在使用 react-bootstrap 创建一个 4 列网格,并希望在每次 idx%4==0 迭代时渲染一个 <Row> 标签,并在每个 idx%4==3 迭代时渲染一个 </Row>

render(){

   {items.map( (item, idx) => (
       idx%4==0? <Row> : '' 

       <Col key={item} lg={3}>
            ....
       <Col>

       idx%4==3? </Row> : ''

    }
}

可以这样做吗?如果没有结束标签,我似乎无法单独做一个开始标签

或者我应该一次切片 4 个并尝试渲染它?

【问题讨论】:

  • 是的,这样就可以了
  • 它不起作用 - 它不喜欢只有一个标签 - 需要一个结束 并且语法有一个错误,我请求帮助。
  • 哦,等等,我误会你了,不,你不能在不关闭 JSX 标签的情况下渲染它们
  • @Ryan 刚刚给你写了一个答案,如果对你有帮助,请告诉我。
  • 也许可以试试 Fragments 而不是空引号

标签: reactjs react-bootstrap


【解决方案1】:

您应该尝试像这样组织语法和三元运算符,以便更好地了解正在发生的事情:

render(){
  {items.map((item, idx) => {
    return(
      idx % 4 == 0 ? (
        <Row>
          <Col>Hello</Col>
        </Row>
      ) : (
        idx % 4 == 3 ? (
          <Row>
            <Col>Different type of hello</Col>
          </Row>
        ) : (
          null
        )
      )
    )
  })}
}

这样您的地图会更简洁一些,生成完全不同的行,而不是尝试将所有内容嵌套在一个条件中。

【讨论】:

  • @Ryan,很高兴你同意。实现你想要的任何运气?如果需要,我很乐意提供帮助。
【解决方案2】:

我认为你的想法是正确的。您可以通过使用索引检查 &amp;&amp; 有条件地渲染而不是三元来清理它 -

{items.map( (item, idx) => (
   {idx % 4 == 0 && <Row>}

     <Col key={item} lg={3}>
        ....
     <Col>

   {idx % 4 == 3 && </Row>}
}

【讨论】:

    【解决方案3】:

    React 你应该渲染(或返回)一个完整的组件,但你可以做这样的事情来对组件进行分组并返回由Row 包裹的完整组:

        return (
          <>
            {items
              .reduce(
                (rows, key, index) =>
                  (index % 3 === 0
                    ? rows.push([key])
                    : rows[rows.length - 1].push(key)) && rows,
                []
              )
              .map((items, idx) => (
                <Row key={idx}>
                  {items.map(item => (
                    <Col key={item} lg={3}>{item}</Col>
                  ))}
                </Row>
              ))}
          </>
        );
    

    reduce 正在创建一个二维数组,每行包含 3 列。

    一个工作示例

    class App extends React.Component {
      render() {
        let myArr = [1, 2, 3, 4, 5, 6, 7, 8];
        return (
          <div>
            {myArr
              .reduce(
                (rows, key, index) =>
                  (index % 3 === 0
                    ? rows.push([key])
                    : rows[rows.length - 1].push(key)) && rows,
                []
              )
              .map((items, idx) => console.log(items) || (
                <ol key={idx}>
                  {items.map(item => console.log(item) || (
                    <li key={item} lg={3}>{item}</li>
                  ))}
                </ol>
              ))}
          </div>
        );
      }
    }
    
    const rootElement = document.getElementById("root");
    ReactDOM.render(<App />, rootElement);
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.6.3/umd/react.production.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.6.3/umd/react-dom.production.min.js"></script>
    <div id="root"></div>

    【讨论】:

      【解决方案4】:

      您可以先创建Col 数组,然后在第二次迭代中创建行

      render() {
          const cols = items.map( (item, idx) => ( 
      
             <Col key={item} lg={3}>
                  ....
             <Col>
             );
             
          const noRows =  Math.ceil(items.length / 4);
      
          const rows = Array.from(Array(noRows)).map((n, i) =>(
            <Row>
             {cols.slice(i* 4, (i + 1)* 4)}
            </Row>
          ));
      
          return rows;
      }

      【讨论】:

      • 谢谢!这正是我所需要的——而且比 reduce() 答案更容易阅读。
      • 太棒了,如果你有 lodash 依赖,那么_.range(noRows),map() 会减少一点代码:)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-09-23
      • 1970-01-01
      • 1970-01-01
      • 2018-12-20
      • 1970-01-01
      • 2020-02-18
      • 1970-01-01
      相关资源
      最近更新 更多