생활코딩 : 리액트편을 보고 작성된 게시글 입니다.
Prop & State
Props : 사용자가 컴포넌트를 사용하는 입장에서 중요한 것(사용자가 컴포넌트를 조작하게 해주는 것)
State : Props의 값에 따라 내부 구현에 필요한 데이터들(컴포넌트 내부적으로 사용되는 것들, 사용자는 알아서는 안됨 + 딱히 알 필요도..)
사용자들에게 Prop의 값을 알려주지 않을 수 있게됨
외부에서 알지 않아도 되는 정보를 철저하게 은닉함
Constructor(prop)
Component가 실행될 때, render()보다 먼저 실행되어서 state값을 초기화 시켜주는 코드
가장 먼저 실행되어 초기화를 담당하는 함수
1개의 값 전달하기 (변수 이용)
import React, { Component } from 'react';
import './App.css';
import TOC from "./components/TOC";
import Subject from "./components/Subject"
import Content from './components/Content';
class App extends Component {
//App Component의 State
constructor(props){ //state를 초기화 시킨 후 props값들을 setting
super(props);
this.state ={
subject:{title:"WEB", sub:"world wide web!"}
}
}
render(){
return (
<div className="App">
<Subject title={this.state.subject.title} sub={this.state.subject.sub}></Subject>
<Subject title="WEB2" sub="world wide web2"></Subject>
<TOC></TOC>
<Content title="HTML" desc="HTML is HyperText Markup Language."></Content>
</div>
);
}
}
export default App;
상위 컴포넌트인 App의 State를 하위 컴포넌트로 전달하고 싶을 때
상위 컴포넌트(ex. App) State 값을 하위 컴포넌트(ex. Subject, TOC, Content )의 prop의 값으로 전달하는 것이 가능함!
여러개의 값 전달하기 (배열이용)
여러개의 값을 전달할 때, 상위 컴포넌트(App)의 내부 State를 주입하는 형식으로 자동으로 하위 컴포넌트(TOC) 데이터를 바뀌게 하기
목차를 보여주던 TOC 컴포넌트를 상위 컴포넌트인 App.js에 작성해두고 넘겨주는 형식으로 변화 시켜보기
1) 상위 컴포넌트의 State에서 준비하기
하위 컴포넌트에 데이터로 보여질 값을 상위 컴포넌트 State로 준비하기
contents 라는 State내의 배열을 만들고 데이터를 넣어줌
class App extends Component {
constructor(props){ //state를 초기화 시킨 후 props값들을 setting
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'}
]
}
}
render(){ //생략 }
export default App;
2) 속성값 지정
class App extends Component {
constructor(props){
//생략
}
render(){
return (
<div className="App">
<Subject title={this.state.subject.title} sub={this.state.subject.sub}></Subject>
<Subject title="WEB2" sub="world wide web2"></Subject>
<TOC data={this.state.contents}></TOC>
<Content title="HTML" desc="HTML is HyperText Markup Language."></Content>
</div>
);
}
}
TOC에 data라는 이름의 속성값을 부여해서 state.contents를 값으로 넘겨줌
3) 하위 컴포넌트에 값 넘겨주기
TOC.js 원래 코드
class TOC extends Component{
render(){
return(
<nav>
<ul>
<li><a href="1.html">HTML</a></li>
<li><a href="2.html">CSS</a></li>
<li><a href="3.html">JavaScript</a></li>
</ul>
</nav>
);
}
}
넘겨받은 data contents의 id, title값을 이용하면 아래와 같은 형식을 반복문으로 생성해 낼 수 있음
<li><a href="링크"></a>제목</li>
lists라는 배열을 만들어 위와 같은 형식을 반복문으로 작성해서 넣어줌
class TOC extends Component{
render(){
var lists = []; //html내의 list를 반복적으로 출력해줄 리스트
var data = this.props.data;
//컴포넌트의 속성으로 들어온 data값을 저장해줌 -> 상위 컴포넌트에서 state에 주어진 content배열임
var i = 0; //반복문을 위한 변수
//<li><a href=?>??</a></li> 형식을 지켜 리스트에 넣어줌
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>
);
}
}
사실상 lists내부 내용과 원래 코드부분의 3줄 내용이 같음을 알 수 있음!
이 방법을 사용하면 오류가 발생하는데 react내부에서 각각의 요소들을 구별하기 위한 key값을 요구하기 때문
key
react내부에서 각각의 요소들을 구별할 수 있게 만들어 줌
lists.push(<li><a href={"/content/"+data[i].id}>{data[i].title}</a></li>);
이 부분에 key값을 추가해주면 해결
lists.push(<li key={data[i].id}><a href={"/content/"+data[i].id}>{data[i].title}</a></li>);
단순하게 key라는 부분에 식별이 가능하도록 identity한 값을 넣어주면 됨
상위 컴포넌트의 state에서 css부분을 지워보면?
class App extends Component {
constructor(props){ //state를 초기화 시킨 후 props값들을 setting
super(props);
this.state ={
subject:{title:"WEB", sub:"world wide web!"},
contents : [
{id:1, title:'HTML', desc:'HTML is for information'},
{id:3, title:'JavaScript', desc:'JavaScript is for interactive'}
]
}
}
render(){ //생략 }
export default App;
TOC를 수정하지 않았음에도 자동으로 TOC에서 CSS목차가 사라진 것을 확인가능!
참고영상
생활코딩
- React 15.1. State소개
- React 15.2. State사용
- React 15.3 key
'Frontend > React' 카테고리의 다른 글
[React] Create기능 구현 (0) | 2020.11.18 |
---|---|
[React] Event (0) | 2020.11.18 |
[React] Component (0) | 2020.11.17 |
[React]기초용어 + build (0) | 2020.11.17 |
[React] 개발환경 만들기 (0) | 2020.11.17 |