javascript - helmet - react map用法




在React JSX中循環 (20)

ES2015 Array.from與地圖功能+鍵

如果你沒有.map()東西,你可以使用Array.from()mapFn來重複元素:

<tbody>
  {Array.from({ length: 5 }, (v, k) => <ObjectRow key={k} />)}
</tbody>

我正在嘗試在React JSX(其中ObjectRow是一個單獨的組件)中執行以下操作:

<tbody>
    for (var i=0; i < numrows; i++) {
        <ObjectRow/>
    } 
</tbody>

我意識到並理解為什麼這不是有效的JSX,因為JSX映射到函數調用。 但是,來自模板領域並且是JSX的新手,我不確定如何實現上述目標(多次添加組件)。


...或者,您也可以準備一個對像數組並將其映射到函數以獲得所需的輸出。 我更喜歡這個,因為它有助於我在渲染返回內部保持不帶邏輯的編碼的良好實踐。

render() {
const mapItem = [];
for(let i =0;i<item.length;i++) 
  mapItem.push(i);
const singleItem => (item, index) {
 // item the single item in the array 
 // the index of the item in the array
 // can implement any logic here
 return (
  <ObjectRow/>
)

}
  return(
   <tbody>{mapItem.map(singleItem)}</tbody>
  )
}

不知道這是否適合您的情況,但通常map是一個很好的答案。

如果這是你用for循環的代碼:

<tbody>
    for (var i=0; i < objects.length; i++) {
        <ObjectRow obj={objects[i]} key={i}>
    } 
</tbody>

你可以像這樣用map寫下來:

<tbody>
    {objects.map(function(object, i){
        return <ObjectRow obj={object} key={i} />;
    })}
</tbody>

ES6語法:

<tbody>
    {objects.map((object, i) => <ObjectRow obj={object} key={i} />)}
</tbody>

以下是來自React文檔的示例: https://facebook.github.io/react/docs/jsx-in-depth.html#javascript-expressions-as-childrenhttps://facebook.github.io/react/docs/jsx-in-depth.html#javascript-expressions-as-children

function Item(props) {
  return <li>{props.message}</li>;
}

function TodoList() {
  const todos = ['finish doc', 'submit pr', 'nag dan to review'];
  return (
    <ul>
      {todos.map((message) => <Item key={message} message={message} />)}
    </ul>
  );
}

作為你的情況,我建議你這樣寫:

function render() {
  return (
    <tbody>
      {numrows.map((roe, index) => <ObjectRow key={index} />)}
    </tbody>
  );
}

請注意Key是非常重要的,因為React使用Key來區分數組中的數據。


你可以做一些事情:

let foo = [1,undefined,3]
{ foo.map(e => !!e ? <Object /> : null )}


使用ES6語法簡單地使用map Array方法:

<tbody>
  {items.map(item => <ObjectRow key={item.id} name={item.name} />)} 
</tbody>

不要忘記key財產。


做這件事有多種方式。 JSX最終會被編譯成JavaScript,所以只要你寫了有效的JavaScript,你就會很好。

我的答案旨在鞏固已經提出的所有美妙方式:

如果你沒有一個對像數組,簡單的行數:

return塊中,創建一個Array並使用Array.prototype.map

render() {
  return (
    <tbody>
      {Array(numrows).fill(null).map((value, index) => (
        <ObjectRow key={index}>
      ))}
    </tbody>
  );
}

return塊外部,只需使用普通的JavaScript for-loop:

render() {
  let rows = [];
  for (let i = 0; i < numrows; i++) {
    rows.push(<ObjectRow key={i}/>);
  } 
  return (
    <tbody>{rows}</tbody>
  );
}

立即調用函數表達式:

render() {
  return (
    <tbody>
      {() => {
        let rows = [];
        for (let i = 0; i < numrows; i++) {
          rows.push(<ObjectRow key={i}/>);
        }
        return rows;
      }}
    </tbody>
  );
}

如果你有一個對像數組

return塊中,將每個對象的.map()轉換為<ObjectRow>組件:

render() {
  return (
    <tbody>
      {objectRows.map((row, index) => (
        <ObjectRow key={index} data={row} />
      ))}
    </tbody>
  );
}

return塊外部,只需使用普通的JavaScript for-loop:

render() {
  let rows = [];
  for (let i = 0; i < objectRows.length; i++) {
    rows.push(<ObjectRow key={i} data={objectRows[i]} />);
  } 
  return (
    <tbody>{rows}</tbody>
  );
}

立即調用函數表達式:

render() {
  return (
    <tbody>
      {() => {
        let rows = [];
        for (let i = 0; i < objectRows.length; i++) {
          rows.push(<ObjectRow key={i} data={objectRows[i]} />);
        }
        return rows;
      }}
    </tbody>
  );
}

如果numrows是一個數組,並且非常簡單。

<tbody>
   {numrows.map(item => <ObjectRow />)}
</tbody>

React中的數組數據類型非常好,數組可以返回新數組,並支持過濾,減少等。


如果你已經在使用lodash,那麼_.times函數很方便。

import React, { Component } from 'react';
import Select from './Select';
import _ from 'lodash';

export default class App extends Component {
    render() {
        return (
            <div className="container">
                <ol>
                    {_.times(3, i =>
                        <li key={i}>
                            <Select onSelect={this.onSelect}>
                                <option value="1">bacon</option>
                                <option value="2">cheez</option>
                            </Select>
                        </li>
                    )}
                </ol>
            </div>
        );
    }
}

如果你還沒有像@ FakeRainBrigand的答案那樣map()的數組,並且想要內聯這個,那麼源佈局對應的輸出比@ SophieAlpert的答案更接近:

借助ES2015(ES6)語法(擴展和箭頭函數)

http://plnkr.co/edit/mfqFWODVy8dKQQOkIEGV?p=preview

<tbody>
  {[...Array(10)].map((x, i) =>
    <ObjectRow key={i} />
  )}
</tbody>

Re:與Babel一起發布,它的警告頁面Array.from是傳播所必需的,但是目前( v5.8.23 ),傳播實際Array時似乎並不是這種情況。 我有一個文檔問題,以澄清這一點。 但是請自擔風險或使用polyfill。

香草ES5

Array.apply

<tbody>
  {Array.apply(0, Array(10)).map(function (x, i) {
    return <ObjectRow key={i} />;
  })}
</tbody>

內聯IIFE

http://plnkr.co/edit/4kQjdTzd4w69g8Suu2hT?p=preview

<tbody>
  {(function (rows, i, len) {
    while (++i <= len) {
      rows.push(<ObjectRow key={i} />)
    }
    return rows;
  })([], 0, 10)}
</tbody>

來自其他答案的技術組合

保持與輸出相對應的源佈局,但使內聯部分更緊湊:

render: function () {
  var rows = [], i = 0, len = 10;
  while (++i <= len) rows.push(i);

  return (
    <tbody>
      {rows.map(function (i) {
        return <ObjectRow key={i} index={i} />;
      })}
    </tbody>
  );
}

使用ES2015語法和Array方法

使用Array.prototype.fill您可以將其作為使用傳播的替代方法,如上所示:

<tbody>
  {Array(10).fill(1).map((el, i) =>
    <ObjectRow key={i} />
  )}
</tbody>

(我認為你實際上可以省略任何參數來fill() ,但我不是100%)。感謝@FakeRainBrigand在fill()解決方案的早期版本中糾正我的錯誤(請參閱修訂版)。

key

在所有情況下, key attr緩解發展構建的警告,但兒童無法訪問。 如果您希望子項中可用索引,則可以傳遞額外的attr。 請參閱列表和鍵以供討論。


很好的問題。

當我想添加一定數量的組件時,我所做的就是使用輔助函數。

定義一個返回JSX的函數:

const myExample = () => {
    let myArray = []
    for(let i = 0; i<5;i++) {
        myArray.push(<MyComponent/>)
    }
    return myArray
}

//... in JSX

<tbody>
    {myExample()}
</tbody>

您的JSX代碼將編譯為純JavaScript代碼,任何標籤都將被ReactElement對象替換。 在JavaScript中,您不能多次調用函數來收集其返回的變量。

這是非法的,唯一的方法是使用數組來存儲函數返回的變量。

或者你可以使用自JavaScript ES5以來可用的map來處理這種情況。

也許我們可以編寫其他編譯器來重新創建一個新的JSX語法來實現像Angular的ng-repeat一樣的重複函數。


您需要將元素添加到數組並呈現元素數組。
這可以幫助減少重新渲染組件所需的時間。

以下是一些可能有所幫助的粗略代碼:

MyClass extends Component {
    constructor() {
        super(props)
        this.state = { elements: [] }
    }
    render() {
        return (<tbody>{this.state.elements}<tbody>)
    }
    add() {
        /*
         * The line below is a cheap way of adding to an array in the state.
         * 1) Add <tr> to this.state.elements
         * 2) Trigger a lifecycle update.
         */
        this.setState({
            elements: this.state.elements.concat([<tr key={elements.length}><td>Element</td></tr>])
        })
    }
}

我傾向於贊成編程邏輯發生在render返回值之外的方法。 這有助於保持實際上易於理解的內容。

所以我可能會這樣做:

import _ from 'lodash';

...

const TableBody = ({ objects }) => {
  const objectRows = objects.map(obj => <ObjectRow object={obj} />);      

  return <tbody>{objectRows}</tbody>;
} 

無可否認,這是少量的內聯代碼,可能會正常工作。


我喜歡它

<tbody>
{ numrows ? (
   numrows.map(obj => { return <ObjectRow /> }) 
) : null}
</tbody>

把它想像成你只是在調用JavaScript函數。 你不能在函數調用中放置一個for循環:

return tbody(
    for (var i = 0; i < numrows; i++) {
        ObjectRow()
    } 
)

但是你可以創建一個數組,然後將其傳遞給:

var rows = [];
for (var i = 0; i < numrows; i++) {
    rows.push(ObjectRow());
}
return tbody(rows);

使用JSX時,您可以使用基本相同的結構:

var rows = [];
for (var i = 0; i < numrows; i++) {
    // note: we add a key prop here to allow react to uniquely identify each
    // element in this array. see: https://reactjs.org/docs/lists-and-keys.html
    rows.push(<ObjectRow key={i} />);
}
return <tbody>{rows}</tbody>;

順便說一句,我的JavaScript例子幾乎就是JSX轉換成的例子。 利用Babel REPL來體驗JSX的工作方式。


有幾個答案指向使用map語句。 下面是一個完整的示例,它使用FeatureList組件中的迭代器根據名為features的JSON數據結構列出Feature組件。

const FeatureList = ({ features, onClickFeature, onClickLikes }) => (
  <div className="feature-list">
    {features.map(feature =>
      <Feature
        key={feature.id}
        {...feature}
        onClickFeature={() => onClickFeature(feature.id)}
        onClickLikes={() => onClickLikes(feature.id)}
      />
    )}
  </div>
); 

您可以在GitHub上查看完整的FeatureList代碼這裡列出了特徵夾具


讓我們說我們有你們國家的一系列物品:

[{name: "item1", id: 1}, {name: "item2", id: 2}, {name: "item3", id: 3}]

<tbody>
    {this.state.items.map((item) => {
        <ObjectRow key={item.id} name={item.name} />
    })} 
</tbody>

這可以通過多種方式完成。

  1. 如上所述,在return存儲數組中的所有元素之前
  2. 循環內return

    方法1

     let container =[];
        let arr = [1,2,3] //can be anything array, object 
    
        arr.forEach((val,index)=>{
          container.push(<div key={index}>
                         val
                         </div>)
            /** 
            * 1. All loop generated elements require a key 
            * 2. only one parent element can be placed in Array
            * e.g. container.push(<div key={index}>
                                        val
                                  </div>
                                  <div>
                                  this will throw error
                                  </div>  
                                )
            **/   
        });
        return (
          <div>
             <div>any things goes here</div>
             <div>{container}</div>
          </div>
        )
    

    方法2

       return(
         <div>
         <div>any things goes here</div>
         <div>
            {(()=>{
              let container =[];
              let arr = [1,2,3] //can be anything array, object 
              arr.forEach((val,index)=>{
                container.push(<div key={index}>
                               val
                               </div>)
                             });
                        return container;     
            })()}
    
         </div>
      </div>
    )
    






reactjs