이전 시간에 state는 subject라고 하는 property 값 하나입니다.
하지만 여러가지 값을 다룰 때에는 사용법이 조금 달라지게 됩니다. 그 방법을 한번 살펴보겠습니다.
현재 프로그램은 <TOC>의 글목록이 추가될 때마다 TOC를 열어서 수정해야합니다.
상위 컴포넌트 <App> 의 내부 state를 <TOC>에 주입하는 것을 통해서 <TOC> 내부 데이터가 자동으로 바뀌도록 변경해보겠습니다.
constructor (props){
super(props);
this.state = {
subject : { title : 'WEB' , sub : 'World Wide 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 interactive'},
]
}
}
contents 라고 하는 property 를 state에 추가하고 데이터 객체가 여러 개이기 때문에 대괄호를 열어서 배열을 만들었습니다.
contents에 담겨있는 배열 정보를 <TOC> 컴포넌트에 주입하고 싶을 때는 어떻게 할까요?
<TOC data={this.stat.contents}></TOC>
<TOC> 컴포넌트에 "data" 라고 하는 props로 {this.state.contetnts} 를 주입시켰습니다.
이제 <TOC> 컴포넌트는 내부적으로 this.props.data라고 하는 값을 갖게 됩니다. 이 값을 이용해서 글 목록을 생성하겠습니다.
class TOC extends Component{
render(){
var lists=[ ];
var data=this.props.data;
var i=0;
while( i < data.length ) {
lists.push( <li><a href={"/content"+data[i].id}>{data[i].title}</a></li>);
i=i+1;
}
return(
<nav>
<ul>
{lists}
</ul>
</nav>
);
}
}
위 코드를 통해 <li> 태그가 하나 하나 생성되서 "lists" 라는 변수에 담기게 됩니다.
이렇게 생성한 lists 배열을 return하면 이전과 똑같이 작동합니다.
하지만 App의 state의 값 하나를 지우고 저장하면 목록이 자동으로 바뀌게 됩니다.
즉, 더 이상 toc.js라고 하는 파일을 열고 data가 바뀐 상태에 따라 로직을 바꾸지 않아도 되는 상태가 되었습니다.
이때 한가지 주의할 것은 엘리먼트 여러개를 자동으로 생성하는 경우에 콘솔 창에 에러가 발생하게 됩니다.
이 에러의 내용은 리스트 항목들은 key라고 하는 props를 가지고 있어야 한다는 의미입니다.
lists.push( <li key={data[i].id}><a href={"/content"+data[i].id}>{data[i].title}</a></li>);
여러 개의 목록을 자동으로 생성할 때에는 각각의 목록을 다른것 들과 구분할 수 있는 식별자를 key를 통해 적어주셔야 합니다.
key는 애플리케이션에서 사용한다기 보다는 리액트가 내부적으로 필요하기 때문에 요청하는 값입니다.
이번 시간에는 "state" 와 "props"의 복잡미묘한 관계를 좀 더 살펴보았습니다.
부모인 <App/> 의 입장에서는 state라고 하는 내부정보를 사용했고 그것을 자식한테 전달할 때는 props를 통해서 전달하고
<App>의 입장에서는 토픽이 내부적으로 어떻게 돌아가는지 알필요가 없게 됩니다.
data 라고 하는 props로는 어떤 형태의 정보를 전달하면 되는가라는 사용자의 입장에서 알아야 될 것만 알면 되는 것입니다.
생각해보기
props와 state의 차이에 대해 설명해보세요.