React JSX 내부 루프
React에서 다음과 같은 작업을 시도하고 있습니다 JSX
(ObjectRow는 별도의 구성 요소입니다).
<tbody>
for (var i=0; i < numrows; i++) {
<ObjectRow/>
}
</tbody>
함수 호출에 매핑 JSX
되기 때문에 이것이 유효하지 않은 이유를 알고 이해 JSX
합니다. 그러나 템플릿 랜드에서 왔고을 (를 JSX
) 처음 사용하는 경우 위의 작업을 수행하는 방법이 확실하지 않습니다 (구성 요소를 여러 번 추가).
JavaScript 함수를 호출하는 것처럼 생각하십시오. for
함수 호출에 대한 인수가 이동 하는 루프를 사용할 수 없습니다 .
return tbody(
for (var i = 0; i < numrows; i++) {
ObjectRow()
}
)
함수 tbody
가 for
루프를 인수로 전달하는 방법을 확인하십시오. 물론 이는 구문 오류입니다.
그러나 배열을 만든 다음 인수로 전달할 수 있습니다.
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의 작동 방법에 대한 느낌을 얻을 수 있습니다.
이것이 귀하의 상황에 맞는지 확실하지 않지만 종종 지도 가 좋은 대답입니다.
이것이 for 루프가있는 코드 인 경우 :
<tbody>
for (var i=0; i < objects.length; i++) {
<ObjectRow obj={objects[i]} key={i}>
}
</tbody>
<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>
map()
@FakeRainBrigand의 답변 을 좋아 하는 배열이 아직없고 소스 레이아웃이 @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 %는 아닙니다.) fill()
솔루션 의 이전 버전에서 실수를 수정 한 @FakeRainBrigand에게 감사드립니다 (개정판 참조).
key
모든 경우에 key
속성은 개발 빌드에서 경고를 완화하지만 자식에서는 액세스 할 수 없습니다. 자식에서 인덱스를 사용할 수 있도록하려면 추가 속성을 전달할 수 있습니다. 자세한 내용은 목록 및 키 를 참조하십시오 .
ES6 구문으로 map Array 메서드를 사용하기 만하면 됩니다 .
<tbody>
{items.map(item => <ObjectRow key={item.id} name={item.name} />)}
</tbody>
key
재산을 잊지 마십시오 .
사용 배열 맵 함수는 루프를 통해 매우 일반적인 방법입니다 배열 요소를 만들고 구성 요소가 그들에 따라 반작용 이 꽤 효율적에 루프 할 수있는 깔끔한 방법입니다 루프 할 수있는 좋은 방법입니다 JSX은 , 그건 하지 만 하지만 선호하는 방법입니다.
또한 필요에 따라 각 반복마다 고유 한 키 를 갖는 것을 잊지 마십시오 . Map 함수 는 0에서 고유 인덱스를 생성하지만 생성 된 인덱스를 사용하는 것은 권장되지 않지만 값이 고유하거나 고유 한 키가있는 경우 사용할 수 있습니다.
<tbody>
{numrows.map(x=> <ObjectRow key={x.id} />)}
</tbody>
또한 Array의 map 기능에 익숙하지 않은 경우 MDN의 몇 줄 :
map은 배열의 각 요소에 대해 제공된 콜백 함수를 순서대로 한 번씩 호출하고 결과에서 새 배열을 구성합니다. 콜백은 undefined를 포함하여 값이 할당 된 배열의 인덱스에 대해서만 호출됩니다. 배열의 누락 된 요소 (즉, 설정되지 않았거나 삭제되었거나 값이 할당되지 않은 인덱스)에 대해서는 호출되지 않습니다.
콜백은 요소의 값, 요소의 인덱스 및 순회되는 Array 객체의 세 가지 인수로 호출됩니다.
thisArg 매개 변수가 매핑에 제공되면 콜백의이 값으로 사용됩니다. 그렇지 않으면 undefined 값이이 값으로 사용됩니다. 콜백이 궁극적으로 관찰 할 수있는이 값은 함수에서 확인하는 일반적인 규칙에 따라 결정됩니다.
map은 호출 된 배열을 변경하지 않습니다 (콜백이 호출되면 그렇게 할 수 있음).
이미 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>
);
}
}
리턴 블록 외부에서 추출 할 수도 있습니다.
render: function() {
var rows = [];
for (var i = 0; i < numrows; i++) {
rows.push(<ObjectRow key={i}/>);
}
return (<tbody>{rows}</tbody>);
}
이것이 오래된 스레드라는 것을 알고 있지만 React Templates 를 확인하고 싶을 수도 있습니다. React Templates 를 확인 하면 몇 가지 지시문 (예 : rt-repeat)과 함께 react에서 jsx 스타일 템플릿을 사용할 수 있습니다.
react-templates를 사용한 경우 예는 다음과 같습니다.
<tbody>
<ObjectRow rt-repeat="obj in objects"/>
</tbody>
numrows가 배열이면 매우 간단합니다.
<tbody>
{numrows.map(item => <ObjectRow />)}
</tbody>
React의 배열 데이터 유형은 매우 우수하며 배열은 새 배열을 지원하고 필터를 지원하고 축소합니다.
이를 수행하는 방법에는 여러 가지가 있습니다. JSX는 결국 자바 스크립트로 컴파일되므로 유효한 자바 스크립트를 작성하는 한 괜찮을 것입니다.
내 대답은 이미 여기에 제시된 모든 멋진 방법을 통합하는 것입니다.
객체 배열이없는 경우 단순히 행 수 :
return
블록 내에서 다음을 만들고 Array
사용합니다 Array.prototype.map
.
render() {
return (
<tbody>
{Array(numrows).fill(null).map((value, index) => (
<ObjectRow key={index}>
))}
</tbody>
);
}
return
블록 외부에서 일반 JavaScript for 루프를 사용하면됩니다.
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 루프를 사용하면됩니다.
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>
);
}
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 에서 전체 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>
... 또는 객체 배열을 준비하고 원하는 출력을 갖도록 함수에 매핑 할 수도 있습니다. 렌더 반환 내부에 로직이없는 코딩의 모범 사례를 유지하는 데 도움이되기 때문에 이것을 선호합니다.
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()
하여 컬렉션을 <ObjectRow>
반복하고 각 반복에서 소품과 함께 항목을 반환 합니다.
objects
어딘가에 배열 이라고 가정합니다 ...
<tbody>
{ objects.map((obj, index) => <ObjectRow obj={ obj } key={ index }/> ) }
</tbody>
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>
이것을 render 메서드 의 return () 안에서 변환하기로했다면 가장 쉬운 방법은 map () 메서드를 사용하는 것 입니다. 아래와 같이 map () 함수를 사용하여 배열을 JSX 구문으로 매핑합니다 ( ES6 구문이 사용됨 ).
내부 부모 구성 요소 :
<tbody>
{ objectArray.map((object, index) => <ObjectRow key={index} object={object}>) }
</tbody>
key
하위 구성 요소에 추가 된 속성에 유의하십시오 . 키 속성을 제공하지 않은 경우 콘솔에서 다음 경고를 볼 수 있습니다.
경고 : 배열 또는 반복기의 각 하위에는 고유 한 "키"소품이 있어야합니다.
이제 ObjectRow 구성 요소 에서 해당 속성의 개체에 액세스 할 수 있습니다.
ObjectRow 구성 요소 내부
const { object } = this.props
또는
const object = this.props.object
이것은 부모 구성 요소 object
에서 ObjectRow 구성 요소 의 변수 로 전달한 개체를 가져와야 합니다. 이제 목적에 따라 해당 개체의 값을 뱉어 낼 수 있습니다.
참고 문헌 :
나는 이것을 사용한다 :
gridItems = this.state.applications.map(app =>
<ApplicationItem key={app.Id} app={app } />
);
PD : 열쇠를 잊지 마십시오. 그렇지 않으면 경고가 많이납니다!
나는 프로그래밍 논리가의 반환 값 외부에서 발생하는 접근 방식을 선호하는 경향이 render
있습니다. 이렇게하면 실제로 렌더링 된 것을 쉽게 찾을 수 있습니다.
그래서 아마도 다음과 같은 일을 할 것입니다.
import _ from 'lodash';
...
const TableBody = ({ objects }) => {
const objectRows = objects.map(obj => <ObjectRow object={obj} />);
return <tbody>{objectRows}</tbody>;
}
분명히 이것은 인라인이 잘 작동 할 수있는 작은 양의 코드입니다.
물론 다른 답변에서 제안한 것처럼 .map으로 해결할 수 있습니다. 이미 babel을 사용하고 있다면 jsx-control-statements 사용에 대해 생각할 수 있습니다 . 약간의 설정이 필요하지만 가독성 측면에서는 가치가 있다고 생각합니다 (특히 비 반응 개발자의 경우). linter를 사용하는 경우 eslint-plugin-jsx-control-statements도 있습니다.
JSX 코드는 순수한 JavaScript 코드로 컴파일되며 모든 태그는 ReactElement
객체 로 대체됩니다 . JavaScript에서는 반환 된 변수를 수집하기 위해 함수를 여러 번 호출 할 수 없습니다.
그것은 불법이며, 유일한 방법은 배열을 사용하여 함수 반환 변수를 저장하는 것입니다.
또는 이 상황을 처리하기 위해 JavaScript ES5 이후Array.prototype.map
로 사용 가능한 것을 사용할 수 있습니다.
Angularng-repeat
와 같은 반복 함수를 구현하기 위해 새로운 JSX 구문을 다시 생성하는 다른 컴파일러를 작성할 수 있습니다 .
여러 번 반복하고 반환하려면 from
및 map
다음을 사용하여 수행 할 수 있습니다 .
<tbody>
{
Array.from(Array(i)).map(() => <ObjectRow />)
}
</tbody>
어디 i = number of times
ES2015 Array.from with the map function + key
아무것도 없다면 요소를 반복하기 위해 함수 와 함께 .map()
사용할 수 있습니다 .Array.from()
map
<tbody>
{Array.from({ length: 5 }, (value, key) => <ObjectRow key={key} />)}
</tbody>
이것은 여러 가지 방법으로 수행 될 수 있습니다.
- 위에서 제안했듯이
return
모든 요소를 배열에 저장 하기 전에 내부 루프
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> )
JSX 코드 내에서 Javascript 구문을 작성하고 있으므로 Javascript를 중괄호로 묶어야합니다.
row = () => {
var rows = [];
for (let i = 0; i<numrows; i++) {
rows.push(<ObjectRow/>);
}
return rows;
}
<tbody>
{this.row()}
</tbody>
다음은 React 문서의 샘플입니다. 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는 매우 중요합니다.
여기에 간단한 해결책이 있습니다.
var Object_rows=[];
for (var i=0; i < numrows; i++) {
Object_rows.push(<ObjectRow/>)
}
<tbody>
{Object_rows}
</tbody>
매핑 및 복잡한 코드가 필요하지 않습니다. 행을 배열로 푸시하고 값을 반환하여 렌더링하면됩니다.
나는 그것을 사용한다
<tbody>
{ numrows ? (
numrows.map(obj => { return <ObjectRow /> })
) : null
}
</tbody>
좋은 질문입니다.
특정 개수의 구성 요소를 추가하고 싶을 때하는 일은 도우미 기능을 사용하는 것입니다.
JSX를 반환하는 함수를 정의합니다.
const myExample = () => {
let myArray = []
for(let i = 0; i<5;i++) {
myArray.push(<MyComponent/>)
}
return myArray
}
//... in JSX
<tbody>
{myExample()}
</tbody>
자체 호출 함수를 사용할 수도 있습니다.
return <tbody>
{(() => {
let row = []
for (var i = 0; i < numrows; i++) {
row.push(<ObjectRow key={i} />)
}
return row
})()}
</tbody>
다음과 같이 할 수 있습니다.
let foo = [1,undefined,3]
{ foo.map(e => !!e ? <Object /> : null )}
참고 URL : https://stackoverflow.com/questions/22876978/loop-inside-react-jsx
'development' 카테고리의 다른 글
div의 콘텐츠를 하단에 정렬하는 방법 (0) | 2020.09.27 |
---|---|
Ruby on Rails의 nil v. empty v. blank에 대한 간결한 설명 (0) | 2020.09.27 |
Django는 확장됩니까? (0) | 2020.09.27 |
Node.js에 파일 / 디렉토리가 있는지 동 기적으로 확인 (0) | 2020.09.27 |
ArrayList 변환 (0) | 2020.09.27 |