1. map
* 1차원 배열
- map은 리액트에서 반복문을 쓸 때 아주 좋은 방법이다.
- 사용법은 배열을 미리 만들고 map메서드를 불러오면 된다.
<ul>
{['가','나','다','라','마'].map( () => {
return (
<li>hi</li>
);
})}
</ul>
- map은 배열안의 원소들을 하나하나 돌아가면서 return결과로 바꾸는 방식이다. 여기서는 문자를 jsx태그로 바꾸고 있는 것이다. 입력과 출력의 갯수가 같음에 유의하자. 결과는 아래와 같을 것이다.
<ul>
<li>hi</li>
<li>hi</li>
<li>hi</li>
<li>hi</li>
<li>hi</li>
</ul>
- map 안에서 첫 번째 인자를 이용하면 배열안의 원소들을 받아오는 반복문이 가능하다.
<ul>
{['가','나','다','라','마'].map( (v) => {
return (
<li>{v}</li>
);
})}
</ul>
- map안에 첫 번째 인자 v를 넣어주었고, 이를 리스트에 넣어주었다. 이렇게하면 다음과 같이 출력될 것이다.
<ul>
<li>가</li>
<li>나</li>
<li>다</li>
<li>라</li>
<li>마</li>
</ul>
* 2차원 배열
- 바뀌는 쌍을 2개로 했을 때, 2차원 배열로 만드는 방법과 객체로 만드는 방법이 있다.
- 먼저 2차원 배열로 만들어보자. 배열이 복잡해지므로 따로 빼서 만들었다.
fruits = [
['사과', '빨강'],
['귤', '주황'],
['수박', '초록'],
['메론', '연두'],
['포도', '보라'],
];
render() {
return (
<>
<ul>
{this.fruits.map( (v) => {
return (
<li>{ v[0] }의 색은 { v[1] }</li>
)
})}
</ul>
</>
);
}
- 위와 같이 따로 배열을 선언하면 this를 이용해서 불러올 수 있다. 그리고 v가 배열의 원소를 하나씩 가져오는데 여기서는 원소하나가 또 배열이므로 인덱스를 이용해서 꺼내 주었다.
<ul>
<li>사과의 색은 빨강</li>
<li>귤의 색은 주황</li>
<li>수박의 색은 초록</li>
<li>메론의 색은 연두</li>
<li>포도의 색은 보라</li>
</ul>
- 이번에는 객체로 만들어보자.
fruits = [
{ fruit: '사과', color: '빨강'},
{ fruit: '귤', color: '주황'},
{ fruit: '수박', color: '초록'},
{ fruit: '메론', color: '연두'},
{ fruit: '포도', color: '보라'}
];
render() {
return (
<>
<ul>
{this.fruits.map( (v) => {
return (
<li>{ v.fruit }의 색은 { v.color }</li>
)
})}
</ul>
</>
);
}
- 결과는 당연히 위에서 했던 것과 같다.
- 참고로 map에서 두 번째 인자로 인덱스 값을 가져오는 것도 가능하다. 이 때는 map( (v, i) => {}) 와 같이 사용해서 i를 이용하면 된다.
- 위의 코드들에는 한 가지 문제가 있다. 바로 key이다. 반복을 돌 때 고유한 키값을 추가해야한다. 예를 들면 위드 li태그를 다음과 같이 수정해야한다.
<li key={v.fruit + v.color}>
{ v.fruit }의 색은 { v.color }
</li>
- key는 반드시 고유한 값이어야 하므로 최대한 중복이 나지 않는 값을 받도록 하였다.
- 또 다른 문제가 있는데, 이는 반환하는 코드블럭이 너무 길어질 수 있다는 것이다. 이럴 때에는 또 다른 컴포넌트 파일로 만드는 것이 낫다. 이는 따로 아래 props에서 살펴보자.
* reduce 사용하기
- 반복문과 비슷한 기능을 활용하기 위해서 reduce를 배열에 활용하는 것도 좋다. reduce는 배열을 순회하며 단 하나의 결과값을 얻어내고 싶을 때 사용하자.
- 배열.reduce ( (a, c) => a + c) 와 같이 사용한다. a와 c는 임의의 변수인데, a는 누적값을, c는 현재값을 나타낸다. 두 개의 함수 인자를 이용해서 함수를 만들면 된다.
- 배열의 평균을 jsx태그안에서 구현해보자.
<!--
const { result } = this.state
...
-->
<div>
평균 : {result.reduce( (a, c) => a + c ) / result.length}
</div>
- result라는 배열을 순회하면서 합을 누적시켜서 총합을 구해내고, 그것을 배열의 길이로 나누어서 평균을 구했다.
- 참고로 세 번째 인자로 인덱스 값을 받을 수 있다.
2. props
- 앞서 작성했던 태그를 별도의 compo.jsx파일에 컴포넌트로 만들어주었다.
import React, { Component } from 'react';
class Compo extends Component {
render() {
const { valInfo } = this.props;
return (
<li>
{ valInfo.fruit }의 색은 { valInfo.color }
<div>내용내용</div>
</li>
)
}
}
export default Compo;
- 외부로 내보내기 위해서 export 를 해줬음을 알 수 있다.
- 여기서 props가 등장하는데 구조분해 문법으로 this.props를 생략해주었지만 어쨋든 태그 안에서 내용들이 앞에서 봤던 v.fruit가 아니라는 것은 알 수 있다. 앞서 봤던대로 v를 바로 쓰면 v를 인식하지 못한다. 따라서 기존의 파일에서 넘겨준 값을 받도록 this.props를 이용한다. 기존의 파일은 다음과 같이 작성되어 있다.
render() {
return (
<>
<ul>
{this.fruits.map( (v) => {
return (
<Compo key={v.fruit + v.color} valInfo={v}/>
)
})}
</ul>
</>
);
}
- import는 따로 적어두진 않았지만 반드시 해야한다.
- map에서 return으로 <Compo /> 를 하고 있음을 알 수 있다. 여기서 key는 아까와 같이 유일한 값을 갖게 하였고, valInfo라는 임의의 props (html에서는 attribute의 역할) 을 정해서 상속 시켜주었다.
- hook에서 props를 쓰려면 다음과 같이 작성하면 된다.
import React from 'react';
const Compo = ({valInfo}) => {
return (
<li>
<div>{ valInfo.fruit }의 색은 { valInfo.color }</div>
</li>
)
}
export default Compo;
- 화살표 함수의 인자로 props.valInfo가 기본적이지만 props. 을 반복 작성해야함을 피하기위해서 구조분해 문법을 사용하였다.
- 부모로 받은 props를 직접적으로 값을 바꾸면 안된다. props는 반드시 부모가 바꿔야하는데, 만약 바꿔야하는 상황이라면 state를 만들고 거기에 넣어서 사용해야한다. 이렇게 하면 부모에는 영향이 가지 않는다.
- 위의 코드에서 props를 변경하려면 아래와 같이 작성하면 된다.
import React, { useState } from 'react';
const Compo = ({valInfo}) => {
const [color, setColor] = useState(valInfo.color);
const onClick = () {
setColor('몰라');
};
return (
<li>
<div>{ valInfo.fruit }의 색은 { valInfo.color }</div>
<div onClick={onClick}>{color}</div>
</li>
)
}
export default Compo;
- 컴포넌트 내부에서 state를 별도로 다시 선언하였고, useState로 값을 불러왔다.
- 클래스 컴포넌트도 마찬가지로 state = { } 로 state를 선언하고 필요한 부분들을 다시 선언하고 변화시켜야한다.
참고
이 글은 ZeroCho 님의 리액트 무료 강좌를 수강하며 개인적으로 정리하며 쓰는 글입니다.
인프런
유튜브
'Client > React.js' 카테고리의 다른 글
<리액트 기초> Ref와 포커싱 (0) | 2021.02.12 |
---|---|
<리액트 기초> 렌더링 최적화 (0) | 2021.02.10 |
<리액트 기초> import vs require (0) | 2021.02.05 |
<리액트 기초> 코드 개선하기 (0) | 2021.02.03 |
<리액트 기초> 웹팩 데브서버와 핫 리로딩 (0) | 2021.02.01 |