props, state, event -> 삼박자가 맞아야 역동적인 ui구현이 가능해진다!
- WEB 텍스트를 클릭하면 HTML 하단에 Welcome 메세지 출력하기
- 리스트 목록을 클릭하면 그 목록안의 텍스트 내용을 HTML 하단에 출력하기
App component의 state가 바뀌고, 바뀐 component가 state값으로 전달되면서 동적으로 application이 바뀌는 것을 구현한다.
✔ Subject 파일과 Content파일 분리하기 -> Subject.js / Content.js
✔ components 폴더에 삽입
현재 페이지가 welcome페이지인지 raed 페이지 인지 구분하기 위해
this.state={ mode: 'welcome'} 기본값 삽입
또한, mode가 welcome일때 지정할 텍스트도 삽입
state값이 바뀌면 그 state를 가지고 있던 component의 render함수가 다시 호출된다.
render함수 하위에 있는 component의 render함수들도 전부 호출되면서 화면이 다시 로딩된다.
👉render는 어떤 html를 그릴 것인가를 결정한는 함수이기 때문에!
react에서는 state값이나 props값이 바뀌면 해당되는 component의 render함수가 호출되도록 약속되어있다. 즉 화면이 다시 그려진다.
✔ mode의 값에 따라 만들어지는 rendering결과가 달라지도록 조건문 사용
this.state.mode 가 welcome이면~
this.state.mode가 read이면 ~
let _title, _desc = nul;
if(this.state.mode === 'welcome'){
_title = this.state.welcome.title; //title의 값
_desc = this.state.welcome.desc; //desc의 값
}else if(this.state.mode === 'read'){
}
state나 props가 수정되면 reload되는 것을 확인하기 위해 각 컴포넌트의 render()함수 안에 console.log를 찍어본다.
ex
import { Component } from 'react';
class Content extends Component {
render(){
console.log('Content redner');
return(
<article>
<h2>{this.props.title}</h2>
{this.props.desc}
</article>
);
}
}
export default Content;
브라우저가 reload되면서 콘솔창에 하나씩 출력되는것을 확인했다.
개발자도구 창에서 State의 mode값을 변경해본다. state가 변경됨에 따라 연결된 redner함수들이 변경된 component의 state값으로 호출된다.
render함수 수정하기 - header 안에 내용을 풀어헤쳐서 자바스크립트로 넣고, 이걸 다시 packaging한다
render() {
console.log('App redner');
var _title, _desc = null;
if(this.state.mode === 'welcome'){
_title = this.state.welcome.title;
_desc = this.state.welcome.desc;
}else if(this.state.mode === 'read'){
_title = this.state.contents[0].title;
_desc = this.state.contents[0].desc;
}
return (
<div className = "App">
{/* <Subject title={this.state.subject.title}
sub={this.state.subject.sub}></Subject> */}
<header>
<h1><a href="/">{this.state.subject.title}</a></h1>
{this.state.subject.sub}
</header>
<TOC data={this.state.contents}></TOC>
<Content title={_title} desc={_desc}></Content>
</div>
);
}
}
✔ 클릭했을 때 이벤트가 발생하므로 onClick 이벤트 사용 (바닐라js에서는 소문자로 사용했는데 react에서는 on- 뒤에 카멜케이스를 따른다.
📌 WEB을 클릭했을 때 App이라는 Component의 mode값을 read -> welcome으로 바꾸고 싶다.
return (
<div className = "App">
{/* <Subject title={this.state.subject.title}
sub={this.state.subject.sub}></Subject> */}
<header>
<h1><a href="/" onClick={function(e){
e.preventDefault();
this.state.mode = "welcome";
}}>{this.state.subject.title}</a></h1>
{this.state.subject.sub}
</header>
<TOC data={this.state.contents}></TOC>
<Content title={_title} desc={_desc}></Content>
</div>
);
this.state.mode = 'welcome'
을 작성했는데 오류가 발생한다.
이벤트가 호출됐을 때 실행되는 이 함수 안에서는 this의 값이 component 자기 자신을 가리키지 않고, 아무것도 세팅이 안된 상태(undefined
)이다.
✔ this binding을 해주면 된다. bind(this)
-> 이제 this는 component를 가리키게 된다.
state의 값이 바뀌었다고 알려줘야 함 : this.setState
를 사용해야 한다.
bind()
"엮는다, 묶어준다."
render라는 함수가 호출될때, 이 함수 안에서 this
는 호출한 Component 그 자신, 즉 여기서 는 App이다.
콘솔창에 this를 찍어보면 다음과 같다.
여기서!!, 조금 전에 작성한 bind(this)를 삭제해보고 다시 콘솔창에 출력해본다.
obj의 name값이 bindTest()라는 함수에 담기도록 하고 싶은것.
setState()
생성자 component가 최초로 생성되었을 때 가장 먼저 실행되는 constructor 함수 내에서는 this.state = { }형태로 수정하면 된다.
BUT! 이미 component가 생성이 끝난 다음에 동적으로 state 값을 바꾸려면...!
그 때 setState()를 사용한다!!