class App extends Component {
constructor(props) {
super(props);
this.state = {
⭐mode: 'read',
⭐welcome: { title: 'Welcome', desc: 'Hello, React!!' },
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() { //어떤 HTML을 그릴것인가를 결정하는 함수
var _title, _desc = null;
if (this.state.mode === 'welcome') { //state의 mode값이 'weclome' 일 때 실행
_title = this.state.welcome.title;
_desc = this.state.welcome.desc;
} else if (this.state.mode === 'read') { //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>
<TOC data={this.state.contents}></TOC>
<Content title={_title} desc={_desc}></Content>
</div>
);
}
}
mode값이 welcome, read에 따라 실행되는 코드가 바뀜
props, state값이 바뀌면 그 state를 가지고 있는 컴포넌트의 render함수가 다시 호출.
그리고 render함수 하위에 있는 컴포넌트들도 다시 호출 (화면 다시 그려짐)
React에서는 링크 클릭시 event를 발생시켜
state, props를 변경함으로써 페이지 전체가 re-rendering
...
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.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';
=> ❌오류❌<header>
<h1><a href="#" onClick={function (e) {
e.preventDefault();
this.state.mode = 'welcome';
}}
</header>
bind()
함수 추가setState ()
사용<header>
<h1><a href="#" onClick={function (e) {
e.preventDefault();
this.setState({
mode: 'welcome'
});
}.bind(this)}>{this.state.subject.title}</a></h1>
{this.state.subject.sub}
</header>
❗ 하지만 render() 함수 밖에서 onClick 이벤트 함수를 화살표함수로(ES6) 만들면 bind() 없이 this 사용 가능
...
<Subject
title={this.state.subject.title}
sub={this.state.subject.sub}
//onChagePage 이벤트 만들고, 링크 클릭시 함수가 실행되게 하기
onChangPage={function () {
this.setState({
mode: 'welcome' // 클릭시 mode값을 welcome으로 바꾸기
});
}.bind(this)}>
</Subject>
<header>
<h1><a href="#" onClick={function (e) {
e.preventDefault();
this.props.onChangePage();
//Subject 컴포넌트에 onChangePage로 함수가 전달되는데 그 함수를 호출하는 코드
}.bind(this)}>{this.props.title}</a></h1>
{this.props.sub}
</header>
...
//onChangePage이벤트 만들기
<TOC onChangePage={function (id) {
this.setState({
mode: 'read'
});
}.bind(this)} data={this.state.contents}></TOC>
while (i < data.length) {
lists.push(
<li key={data[i].id}>
<a href={"/content/" + data[i].id}
onClick={function (e) {
e.preventDefault();
this.props.onChangPage();
}.bind(this)}
>{data[i].title}</a>
</li>);
i = i + 1;
}
this.state = {
mode: 'read',
⭐selected_content_id = 2, // 기본적으로 2번 contents가 선택되게 함
welcome: { title: 'Welcome', desc: 'Hello, React!!' },
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() {
var _title, _desc, _article = null;
if (this.state.mode === 'welcome') {
_title = this.state.welcome.title;
_desc = this.state.welcome.desc;
}⭐ else if (this.state.mode === 'read') {
var i = 0;
while (i < this.state.contents.length) {
var data = this.state.contents[i]; //현재 순번에 해당되는 contents를 data변수에 지정
if (data.id === this.state.selected_content_id) {
_title = data.title;
_desc = data.desc;
break; //조건문을 끝내는 코드
}
i = i + 1;
}
}
return (
<div className="App">
<TOC onChangePage={function (id) {
this.setState({
mode: 'read',
selected_content_id: Number(id)
// 인자가 문자로 넘어가기 때문에 숫자로 바꿔주는 Number 명령어를 사용
});
}.bind(this)} data={this.state.contents}>
</TOC>
</div>
);
}
while (i < data.length) {
lists.push(
<li key={data[i].id}>
<a href={"/content/" + data[i].id}
data-id={data[i].id} //
onClick={function (e) {
e.preventDefault();
this.props.onChangPage(e.target.dataset.id);
//onChangePage 함수를 호출하는 코드의 인자로 e.target에서 얻어진 id 값을 넘겨줌
}.bind(this)}
>{data[i].title}</a>
</li>);
i = i + 1;
}
e.target
은 a태그를 가리키며, dataset을 통하여 data-id값을 알아낼 수 있음