State의 사용방법 (다중 속성의 경우)
: 앞선 Subject는 겨우 WEB, world wider web! 으로만 이루어져 있는데,
TOC의 경우 ul-li로 감싸진 많은 내용으로 이루어져 있다. 이럴 때는 어떻게 쓸까.
class App extends Component {
constructor(props) {
super(props);
this.state = {
subject:{title:"WEB" sub:"world wider web!"},
contents:[
{id:1, title:'HTML', desc: 'HTML is for information'},
{id:2, title:'CSS', desc: 'CSS is for design'},
{id:3, title:'Javascript', desc: 'Javascript is for exciting'}
]
}
}
render() {
return (
<div className="App">
<Subject title={this.state.subject.title}
sub={this.state.subject.sub}></Subject>
<TOC data={this.state.contents}></TOC>
<Content title="HTML" desc="HTML is Markup Language"></Content>
</div>
);
}
}
export default App;
contents도 subject와 같은 방법이지만 우선 대괄호인 []를 써주고,
그 안에 각각의 괄호를 통해 다중속성을 제어할 수 있다.
상위 컨포넌트인 App의 TOC에는 data라는 props를 받아서 써주었다.
그럼 아직 건들지 않은 TOC 컨포넌트는 어떻게 처리할까?
src > components > Subject, Content, TOC.js
// Subject.js
class Subject extends Component {
render() {
return (
<header>
<h1>{this.props.title}</h1>
{this.props.sub}
</header>
);
}
}
export default Subject;
// Content.js
class Content extends Component {
render() {
return (
<article>
<h2>{this.props.title}</h2>
{this.props.desc}
</article>
)
}
}
export default Content;
// TOC.js
class TOC extends Component {
render() {
return (
<nav>
<ul>
<li><a href="1.html"></a>HTML</li>
<li><a href="2.html"></a>CSS</li>
<li><a href="3.html"></a>JavaScript</li>
</ul>
</nav>
);
}
}
export default TOC;
TOC는 아직 컨포넌트 내용을 수정하지 않은 상태이다.
src > components > TOC.js
import React, { Component } from 'react';
class TOC extends Component {
render() {
var list = [];
var data = this.props.data
var i = 0;
while(i < data.length) {
list.push(<li><a href={"/content/"+data[i].id}>{data[i].title}</a></li>);
i = i + 1;
}
return (
<nav>
<ul>
{list}
</ul>
</nav>
);
}
}
export default TOC;
추가된 부분에 대해 해석을 해보면 이렇다.
var list = []; // list라는 새로운 빈배열을 만든다.
var data = this.props.data // props에서 설명했지만, this.props.data는 state의 contents를 가져온다.
var i = 0;
while(i < data.length) {
list.push(<li><a href={"/content/"+data[i].id}>{data[i].title}</a></li>);
i = i + 1;
}
// 빈 배열에 하나씩 넣어주는데, /content/는 임시 url정도고,
data를 차례대로 id, title값을 가져와 넣어주게 된다.
<li><a href=/content/"+0}>HTML</a></li>
<li><a href=/content/"+1>CSS</a></li>
<li><a href=/content/"+2>JavaScript</a></li>
이 배열을 {list}로 담는다.
=> 이렇게 쓰는 이유는, 예를 들어 TOC의 수정부분이 생길 때마다
TOC안에 들어가서 직접적으로 태그를 수정해주는 것보다,
state의 contetns내용을 수정할 수 있기 때문이다. 앞서 설명한 은닉화도 관련이 있다.
그런데 이렇게 여러개의 엘리먼트를 자동생성하는 경우, 에러가 발생한다.
Warning: Each child in a list should have a unique "key" prop.
(list의 자식 항목들은 key라는 props가 필요하다는 뜻)
list.push(<li key={data[i].id}><a href={"/content/"+data[i].id}>{data[i].title}</a></li>);
key={data[i].id}같은 형식으로 추가해주면 된다.
key값은 무엇이든 상관없고 이런 이름으로 할 것이다. 라고 명시해준다고 이해하면 된다.
'프로그래밍 > React' 카테고리의 다른 글
[React] 클릭이벤트 이해하기 (0) | 2021.01.24 |
---|---|
[React] state 사용하기 (단일속성) (0) | 2021.01.22 |
[React] 컴포넌트별로 파일 분리하기 (0) | 2021.01.22 |
[React] props 사용하기 (0) | 2021.01.22 |
[React] 기본적인 컴포넌트 만들기 (0) | 2021.01.22 |