React JSX 내부 루프


1278

React에서 다음과 같은 작업을 시도하고 있습니다 JSX(ObjectRow는 별도의 구성 요소입니다).

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

함수 호출에 매핑 JSX되기 때문에 이것이 왜 유효하지 않은지 알고 이해 JSX합니다. 그러나 템플릿 토지에서 와서 처음부터 JSX위의 내용을 어떻게 달성할지 확신 할 수 없습니다 (구성 요소를 여러 번 추가).


38
JSX에서는 JavaScript 구문 주위에 {} 태그가 필요합니다. 이것은 facebook.github.io/react/docs/… 도움이 될 수 있습니다 .
이사야 그레이

30
let todos = this.props.todos.map((todo) => {return <h1>{todo.title}</h1>})
OverCoder


@OverCoder 왜 {} 태그에 전체 수익을 넣을까요? => return <h1> {todo.title} </ h1> 그렇지 않습니까?
pravin poudel

1
@pravinpoudel 실제로 그 대답은 오래되었습니다 let todos = this.props.todos.map(t => <h1>{t.title}</h1>):)
OverCoder

답변:


1205

JavaScript 함수를 호출하는 것처럼 생각하십시오. for함수 호출에 대한 인수가가는 루프는 사용할 수 없습니다 .

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

함수 tbodyfor루프가 인수로 전달되는 방법을 살펴보십시오. 물론 구문 오류입니다.

그러나 배열을 만든 다음 인수로 전달할 수 있습니다.

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 예제가 거의 정확하게 변형 된 것입니다. 함께 놀러 바벨 REPL하는 JSX의 작동 방법에 대한 느낌을 얻을 수 있습니다.


3
이 예제는 jsx 컴파일러 에서 컴파일되지 않는 것처럼 컴파일러가 변경 되었을 수 있지만 FakeRainBrigand의 답변에서와 같이 map을 사용하면 올바르게 컴파일되는 것처럼 보입니다.
rav

9
마지막 예제가 최신 JSX 컴파일러에서 올바르게 컴파일된다고 약속 할 수 있습니다.
Sophie Alpert

3
이것은 잘 작동합니다. FakeRainBrigand의 답변은 간단한 배열 반복에 효과적이지만이 답변은 사용할 수없는 시나리오 map(예 : 변수에 컬렉션이 저장되지 않은 경우)에 필수적입니다 .
켈빈

52
리 액트는 dom을 효율적으로 업데이트해야합니다.이 경우 부모는 key각 어린이에게 a 를 할당해야합니다 . REF : facebook.github.io/react/docs/…
qsun

7
이 예제는 작동하지만 key속성과 같은 중요한 비트 및 React 코드베이스에서 실제로 사용되지 않는 코드 스타일이 누락 되었습니다. 이 답변 stackoverflow.com/questions/22876978/loop-inside-react-jsx/… 를 올바른 것으로 간주 하십시오.
okonetchnikov

865

이것이 귀하의 상황에 맞는지 확실하지 않지만 종종 지도 가 좋은 대답입니다.

이것이 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>

43
iteratee가 배열이면 Map이 더 의미가 있습니다. 숫자 인 경우 for 루프가 적합합니다.
Code Whisperer

26
<tbody>{objects.map((o, i) => <ObjectRow obj={o} key={i}/>}</tbody>Reactify의 ES6 지원 또는 Babel을 사용합니다.
Distortum

3
+1. 나는 이것을 ul (정렬되지 않은 목록)과 함께 사용하고 있습니다. <ul> {objects.map((object:string,i:number)=>{ return <li>{object}</li> })} </ul>TypeScript 사용
Roberto C Navarro

5
이것은 훌륭하지만 객체 위에 매핑 할 수는 없습니다. 내가 사용할 것for..in
Damon

4
Object.keys를 사용할 때 키의 순서는 임의적입니다. 키 순서를 별도로 저장하면 필요하고 객체 리터럴의 순서도 잘 작동한다는 것을 알았습니다. 그러면 다음과 같은 코드를 작성할 수 있습니다this.props.order.map((k)=><ObjectRow key={k} {...this.props.items[k]} />)
tgrrr

443

map()@FakeRainBrigand의 답변 을 좋아 하는 배열이없는 경우 소스 레이아웃이 @SophieAlpert의 답변보다 가까운 출력에 해당하도록 인라인하려는 경우 :

ES2015 (ES6) 구문 사용 (확산 및 화살표 기능)

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

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

재 : 바벨과 transpiling, 그것의 주의 사항 페이지 가 말한다 Array.from확산을 위해 필요하지만 현재 ( v5.8.23) 실제를 확산 할 때 경우 될 것 같지 않습니다 Array. 그것을 명확히하기 위해 문서 문제가 열려 있습니다. 그러나 자신의 위험이나 폴리 필로 사용하십시오.

바닐라 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 %는 아닙니다.) 이전 버전의 fill()솔루션 에서 실수를 수정 한 @FakeRainBrigand에게 감사드립니다 (개정판 참조).

key

모든 경우에 keyattr은 개발 빌드에 대한 경고를 완화하지만 자식에서는 액세스 할 수 없습니다. 자식에서 인덱스를 사용할 수있게하려면 추가 속성을 전달할 수 있습니다. 자세한 내용은 목록 및 키 를 참조하십시오 .


2
무엇에 대해 yield? 생성기를 사용할 때 요소를 중간 배열로 푸시하는 것은 추악합니다. 그들이 일하니?
mpen September

2
@ Mark 생성기가 실제로 적용 가능한지 모르겠습니다. JSX와 관련하여 중요한 것은 배열을 반환하는 표현식입니다. 따라서 발전기를 어떻게 든 사용하려는 경우 어쨌든 발전기를 뿌릴 수 있으며 여기 ES2015 기반 솔루션보다 더 장황 할 것입니다.
JMM

2
이것이 어떻게 더 장황합니까? 그리고 왜 JSX가 배열뿐만 아니라 반복 가능한 것을 허용하지 않습니까?
mpen

2
@Mark 그것은 실제로 사용한 (ES5) IIFE 예제보다 장황하지만 [...Array(x)].map(() => <El />)), 가장 우아하다고 생각 하는 버전 보다 더 장황 합니다. 재 : 두 번째 질문은 좋은 지적입니다. JSX에 대해서는 아무것도 배제하지 않는 것으로 보이므로 React 또는 변형 된 JSX의 다른 소비자는 children 인수로 수행하는 작업에 따라 달라집니다. 소스를 보지 않고 말할 수는 없었습니다. 당신은 알고 있습니까? 흥미로운 질문입니다.
JMM

3
@corysimmons Cool 정보에 대한 감사합니다 fill(). 내가 망설 인 이유는 매개 변수의 선택이 ES 사양에 어떻게 표시되는지에 대한 질문이라는 것을 기억합니다 (언제나 살펴 봐야 함). 쉼표는 배열 요소를 제거하는 방법입니다 (이 경우 첫 번째 요소). 인덱스가 스프레드 배열의 0..length-1이 아닌 확산하는 배열의 1..length에서 시작하려는 경우 수행 할 수 있습니다 (제거 된 요소는 배열의 길이에 기여하기 때문에 t 해당하는 속성이 있습니다).
JMM

85

ES6 구문과 함께 map Array 메소드를 사용하기 만하면 됩니다 .

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

key속성을 잊지 마십시오 .


id 대신 임의의 'Math.random ()'키를 추가하면 자식 내부에서 setState를 사용할 때 제대로 작동하지 않습니다. 이유가 무엇입니까?
Oliver D

82

사용 배열 맵 함수는 루프를 통해 매우 일반적인 방법입니다 배열 요소를 만들고 구성 요소가 그들에 따라 반작용 이 꽤 효율적에 루프 할 수있는 깔끔한 방법입니다 루프 할 수있는 좋은 방법입니다 JSX은 , 그건 하지 만 그것을 하는 방법 이지만 선호하는 방법입니다.

또한 필요에 따라 각 반복마다 고유 한 키 를 갖는 것을 잊지 마십시오 . 맵 함수 는 0에서 고유 인덱스를 작성하지만 생성 된 인덱스를 사용하는 것은 좋지 않지만 값이 고유하거나 고유 키가있는 경우이를 사용할 수 있습니다.

<tbody>
  {numrows.map(x=> <ObjectRow key={x.id} />)}
</tbody>

또한 Array의 map 함수에 익숙하지 않은 경우 MDN의 몇 줄 :

map은 배열의 각 요소에 대해 제공된 콜백 함수를 순서대로 한 번 호출하고 결과에서 새 배열을 구성합니다. 콜백은 undefined를 포함하여 값을 할당 한 배열의 인덱스에 대해서만 호출됩니다. 배열의 누락 된 요소 (즉, 설정되지 않았거나 삭제되었거나 값이 지정되지 않은 인덱스)에 대해서는 호출되지 않습니다.

콜백은 요소의 값, 요소의 색인 및 순회되는 Array 객체의 세 가지 인수로 호출됩니다.

thisArg 매개 변수를 맵핑하기 위해 제공하면 콜백의이 값으로 사용됩니다. 그렇지 않으면 undefined 값이이 값으로 사용됩니다. 콜백이 궁극적으로 관찰 할 수있는이 값은 함수에서 볼 수있는이를 결정하기위한 일반적인 규칙에 따라 결정됩니다.

map은 그것이 호출 된 배열을 변경하지 않습니다 (호출되면 콜백이 그렇게 할 수 있습니다).


Array#map비동기가 아닙니다!
philraj

52

이미 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>
        );
    }
}

1
lodash와 같은 라이브러리를 포함하지 않으면 Array.prototype.map이 훌륭한 옵션이 될 수 있습니다. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/... .
이사야 그레이

1
@IsaiahGrey 배열이 이미있는 경우에만 해당됩니다. 때로는 몇 번만 반복하고 싶을 수도 있습니다.
mpen

1
당연하다! 실제 데이터에 따라 다른 많은 접근 방식이 있습니다. 개발 프로세스가 아닌 경우 모델링 된 데이터의 방식으로 인해 맵에 잘 맞을 수 있다는 것을 알게되었습니다. lodash를 사용하는 좋은 예! Btw, 속성 초기화 구문을 사용하여 메소드를 구성 요소에 바인딩하고 있습니까?
이사야 그레이

4
@IsaiahGrey ES6 분석법 정의
mpen

41

리턴 블록 외부에서 추출 할 수도 있습니다.

render: function() {
    var rows = [];
    for (var i = 0; i < numrows; i++) {
        rows.push(<ObjectRow key={i}/>);
    } 

    return (<tbody>{rows}</tbody>);
}

34

나는 이것이 오래된 스레드라는 것을 알고 있지만 React Templates 을 확인하고 싶을 수도 있습니다 .

예를 들어 반응 템플릿을 사용한 경우 다음과 같습니다.

<tbody>
     <ObjectRow rt-repeat="obj in objects"/>
</tbody>

일반 자바 스크립트가 이미 다양한 종류의 for 루프 또는 Array.prototype.map 메소드를 사용하여 문제를 해결하는 동안 추가 라이브러리를 사용하는 이유는 무엇입니까? 나는 이미 현재 프로젝트에서 잘 작동하는 일반 자바 스크립트 방법을 이미 사용했습니다. 가능할 때마다 평범한 자바 스크립트 방법을 사용하는 습관이 있으면 자바 스크립트 기술을 향상시키는 데 도움이됩니다. React-Router를 통한 라우팅과 같은 특정 문제에 대한 솔루션을 찾기가 어려울 때 추가 라이브러리 만 사용합니다.
Lex Soft

27

이를 수행하는 방법에는 여러 가지가 있습니다. 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>
      {(() => {
        const rows = [];
        for (let i = 0; i < objectRows.length; i++) {
          rows.push(<ObjectRow key={i} data={objectRows[i]} />);
        }
        return rows;
      })()}
    </tbody>
  );
}

2
훌륭한 답변 : 다양한 기술, 모두 유사한 작업을 수행하는 다양한 방법으로 인해 자바 스크립트의 힘을 보여주는 일반 자바 스크립트 만 사용합니다.
Lex Soft

24

numrows가 배열이면 매우 간단합니다.

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

React의 배열 데이터 유형이 훨씬 우수합니다. 배열은 새로운 배열을 백업하고 필터를 지원하고 감소시킵니다.


키를 사용하지 않으므로 적절한 답변이 아닙니다.
kojow7

21

map명령문 사용을 가리키는 몇 가지 답변이 있습니다 . 여기 내 반복자하여 완전한 예이다 FeatureList 리스트에 요소 기능 라는 JSON 데이터 구조에 기초하여 구성 요소 기능 .

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 에서 전체 기능 목록 코드 를 볼 수 있습니다 . 기능의 비품은 여기에 나열됩니다 .


fetch API를 사용하여 데이터베이스에서 데이터를 검색 할 때 JSON 데이터를 처리 할 때 Array.prototype.map 메서드를 사용합니다. 그 목적을 위해 편리하고 입증 된 방법입니다.
Lex Soft

17

시간과 수익의 수에 대한 루프에, 당신의 도움으로 그것을 달성 할 수 frommap:

<tbody>
  {
    Array.from(Array(i)).map(() => <ObjectRow />)
  }
</tbody>

어디 i = number of times


렌더링 된 컴포넌트에 고유 키 ID를 지정하려는 경우 React 문서React.Children.toArray 에서 제안한대로 사용할 수 있습니다.

React.Children.toArray

하위 불투명 데이터 구조를 각 하위에 키가 할당 된 평면 배열로 반환합니다. 렌더링 메소드에서 하위 컬렉션을 조작하려는 경우, 특히 this.props.children을 전달하기 전에 순서를 바꾸거나 슬라이스하려는 경우에 유용합니다.

노트 :

React.Children.toArray()자식 목록을 병합 할 때 중첩 배열의 의미를 유지하도록 키를 변경합니다. 즉, toArray는 반환 된 배열의 각 키 앞에 접두사를 붙여 각 요소의 키가 해당 배열을 포함하는 입력 배열로 범위를 지정합니다.

<tbody>
  {
    React.Children.toArray(
      Array.from(Array(i)).map(() => <ObjectRow />)
    )
  }
</tbody>

17

render 메소드 의 return () 내에서 이것을 변환하도록 선택하면 가장 쉬운 옵션은 map () 메소드를 사용하는 것 입니다. 아래와 같이 map () 함수를 사용하여 배열을 JSX 구문으로 매핑합니다 ( ES6 구문 사용 ).


내부 상위 컴포넌트 :

<tbody>
   { objectArray.map(object => <ObjectRow key={object.id} object={object.value}>) }
</tbody>

key하위 구성 요소에 추가 된 속성에 유의하십시오 . 키 속성을 제공하지 않은 경우 콘솔에 다음 경고가 표시됩니다.

경고 : 배열 또는 반복자의 각 자식에는 고유 한 "키"소품이 있어야합니다.

참고 : 사람들이 index반복 하는 실수 중 하나는 키로 사용하는 것 index입니다. 요소를 키로 사용하는 것은 안티 패턴이며 여기에서 자세한 내용을 읽을 수 있습니다 . 요컨대 정적 목록 이 아닌 경우 index키로 사용 하지 마십시오 .


이제 ObjectRow 구성 요소에서 해당 속성에서 객체에 액세스 할 수 있습니다.

내부 ObjectRow 구성 요소

const { object } = this.props

또는

const object = this.props.object

부모 컴포넌트 object에서 ObjectRow 컴포넌트 의 변수 로 전달한 객체를 가져와야 합니다. 이제 목적에 따라 해당 개체의 값을 추출 할 수 있습니다.


참고 문헌 :

자바 스크립트의 map () 메소드

ECMA 스크립트 6 또는 ES6


16

귀하의 주에 여러 항목이 있다고 가정 해 보겠습니다.

[{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>

지도 (항목) 후에 {}을 제거해야 할 수도 있다고 생각합니다.
Ian

15

ES2015 / Babel 가능성은 생성기 함수를 사용하여 JSX 배열을 만듭니다.

function* jsxLoop(times, callback)
{
    for(var i = 0; i < times; ++i)
        yield callback(i);
}

...

<tbody>
    {[...jsxLoop(numrows, i =>
        <ObjectRow key={i}/>
    )]}
</tbody>

15

... 또는 객체 배열을 준비하여 원하는 출력을 갖도록 함수에 매핑 할 수도 있습니다. 렌더링 리턴 내에서 로직없이 코딩의 우수 사례를 유지하는 데 도움이되므로이를 선호합니다.

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>
  )
}

15

.map()컬렉션을 <ObjectRow>반복하고 각 반복에서 소품으로 항목을 반환 하는 데 사용 하십시오 .

objects어딘가에 배열 이라고 가정하면 ...

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

15

ES2015 Array.from 맵 기능 + 키

아무것도없는 경우 함수를 .map()사용 Array.from()하여 map요소를 반복 할 수 있습니다 .

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

15

나는 이것을 사용한다 :

gridItems = this.state.applications.map(app =>
          <ApplicationItem key={app.Id} app={app } />
);

추신 : 열쇠를 잊지 마십시오. 그렇지 않으면 많은 경고가 나타납니다!


또는 아이템에 다음 .Id과 같은 속성 이없는 경우 배열 인덱스를 사용하십시오.items.map( (item, index) => <Foo key={index}>{item}</Foo>
kontur

13

프로그래밍 논리가의 반환 값 외부에서 발생하는 접근 방식을 선호하는 경향이 render있습니다. 이렇게하면 실제로 렌더링하기 쉬운 것을 유지할 수 있습니다.

그래서 아마 다음과 같은 일을 할 것입니다 :

import _ from 'lodash';

...

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

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

분명히 이것은 작은 양의 코드이므로 인라인으로 잘 작동 할 수 있습니다.


객체를 반복하는 lodash 맵의 큰 팬. import { map } from 'lodash'그래도 필요하지 않은 경우 모든 lodash 함수를 가져 오지 않는 경향이 있습니다 .
Stretch0

요즘 우리는 lodash 맵조차 필요하지 않습니다. 단지 배열 위로 직접 매핑하십시오.
Adam Donahue

map(). es6을 사용하여 객체를 반복 할 수는 없으며 배열 만 있습니다. 그것이 lodash가 객체를 반복하는 데 좋다고 말하는 것입니다.
Stretch0

나는 당신 objects이 물건의 목록에서 내 실수 를 의미한다고 생각했습니다 .
Adam Donahue


12

JSX 코드는 순수한 JavaScript 코드로 컴파일되며 모든 태그는 ReactElement객체 로 대체됩니다 . JavaScript에서는 반환 된 변수를 수집하기 위해 함수를 여러 번 호출 할 수 없습니다.

불법입니다. 유일한 방법은 배열을 사용하여 함수가 반환 한 변수를 저장하는 것입니다.

또는 이 상황을 처리하기 위해 JavaScript ES5부터 사용 Array.prototype.map가능한 것을 사용할 수 있습니다.

어쩌면 Angularng-repeat 와 마찬가지로 반복 함수를 구현하기 위해 새로운 JSX 구문을 다시 작성하기 위해 다른 컴파일러를 작성할 수 있습니다 .


12

이것은 여러 가지 방법으로 수행 할 수 있습니다.

  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>
    )

네. 현재 프로젝트에서 메소드 1을 사용합니다. 즉 Array.prototype, forEach () 메소드를 사용하여 데이터베이스의 데이터로 채워지는 HTML 선택 요소를 만듭니다. 그러나지도 메소드가 더 컴팩트 해 보입니다 (코드가 적음). Array.prototype.map () 메소드로 대체 할 가능성이 큽니다.
Lex Soft

10

여기에 간단한 해결책이 있습니다.

var Object_rows=[];
for (var i=0; i < numrows; i++) {
    Object_rows.push(<ObjectRow/>)
} 
<tbody>
  {Object_rows}
</tbody>

매핑과 복잡한 코드가 필요하지 않습니다. 행을 배열로 푸시하고 값을 반환하여 렌더링하면됩니다.


html select 요소를 만들 때이 비슷한 기술이 처음으로 떠오른 것이므로 forEach () 메서드를 사용하지만이 기술을 사용했습니다. 그러나 Lists and Keys 주제에 대한 React 문서를 다시 읽으면 여기에 몇 가지 답변으로 표시된 것처럼 map () 메서드가 사용됩니다. 이것은 내가 선호하는 방법이라고 생각합니다. 더 컴팩트하게 보이기 때문에 (코드가 적음) 동의합니다.
Lex Soft

9

JSX 코드 내에 Javascript 구문을 작성하고 있으므로 Javascript를 중괄호로 묶어야합니다.

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

9

다음은 React doc의 샘플입니다. 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>
  );
}

React는 Key를 사용하여 배열의 데이터를 다르게하므로 Key는 매우 중요합니다.


9

나는 그것을 좋아한다

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


8

좋은 질문입니다.

특정 수의 구성 요소를 추가하려고 할 때 도우미 기능을 사용합니다.

JSX를 리턴하는 함수를 정의하십시오.

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

//... in JSX

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

8

자체 호출 기능을 사용할 수도 있습니다.

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

           })()}
        </tbody>

렌더링 내에서 익명 함수를 사용하는 것은 반응 할 때 좋은 습관으로 간주되지 않습니다. 이러한 함수는 다시 렌더링 할 때마다 다시 만들거나 버려야합니다.
Vlatko Vlahek

@VlatkoVlahek은 렌더 사이클마다 함수 소품을 다시 작성하여 실수를 저 지르므로 대규모 성능이 저하 될 수 있습니다. 다른 곳에서 익명의 기능을 생성해도 성능에 큰 영향을 미치지는 않습니다.
Emile Bergeron

1
@EmileBergeron 이것은 얼마 전 haha입니다. 이것이 소품으로 사용되지 않으면 동의하지 않습니다.
Vlatko Vlahek
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.