
페이지 구분 위한 모드 추가
this.state = { mode: 'welcome', welcome: {title: 'Welcome', desc: 'Hello, React!!'}, ... }
render() {
var _title, _desc = null;
// === (같다): 리액트 문법
if(this.state.mode === 'read') {
_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'>
...
<Content title={_title} desc={_desc}></Content>
</div>
);
}
onClick={ } 의 형태
<a href='/' onClick={function(e){ console.log(e); e.preventDefault(); // debugger; }}>{this.state.subject.title}</a>
<a> 는 기본적으로 페이지 새로고침 기능이 있다
이유 :this는 컴포넌트 자기자신을 가리키는 것이 아닌 아무것도 세팅되어 있지 않은 값. => undefinde 발생.bind(this) 추가, setState() 함수 추가 <a href='/' onClick={function(e){
console.log(e);
e.preventDefault();
// this.state.mode = 'welcome'; 값 바뀌지 않음
this.setState({
mode:'welcome'
});
}.bind(this)}>{this.state.subject.title}</a>
기본적으로 리액트에서
render()함수 내에서this는 컴포넌트 자체, 함수에서는 아무 값도 가지지 않는다. 이때,bind()함수를 통해this를 주입시켜 주는 것이다.
App.js
import React, { Component } from 'react';
import TOC from './components/TOC'
import Content from './components/Content'
import Subject from './components/Subject'
import './App.css';
class App extends Component {
constructor(props) {
super(props);
this.state = {
mode: 'read',
selected_content_id: 2,
subject: { title: 'WEB', sub: 'world wid web!' },
welcome: { title: 'Welcome', desc: 'Hello, React!!' },
contents: [
{ id: 1, title: 'HTML', desc: 'HTML is HyperText' },
{ id: 2, title: 'CSS', desc: 'CSS is design' },
{ id: 3, title: 'JavaScript', desc: 'JavaScript is interactive' },
]
}
}
render() {
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') {
var i = 0;
while(i < this.state.contents.length) {
var data = this.state.contents[i];
if(data.id === this.state.selected_content_id) {
_title = data.title;
_desc = data.desc;
break;
}
i = i + 1;
}
}
return (
<div className='App'>
<Subject
title={this.state.subject.title}
sub={this.state.subject.sub}
onChangePage={function() {
this.setState({mode: 'welcome'});
}.bind(this)}
>
</Subject>
<TOC onChangePage={function (id) { // ⭐TOC.js에서 받아온 id값을 selected_content_id에 넘겨준다
this.setState({
mode: 'read',
selected_content_id:Number(id)
});
}.bind(this)}
data={this.state.contents}></TOC>
<Content title={_title} desc={_desc}></Content>
</div>
);
}
}
export default App;
Subject.js
import React, { Component } from 'react';
class Subject extends Component {
render() {
console.log('Subject render');
return (
<header>
<h1><a href='/' onClick={function(e) {
e.preventDefault();
this.props.onChangePage();
}.bind(this)}>{this.props.title}</a></h1>
{this.props.sub}
</header>
);
}
}
export default Subject;
TOC.js
import React, { Component } from "react";
class TOC extends Component {
render() {
var lists = [];
var data = this.props.data;
var i = 0;
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.onChangePage(e.target.dataset.id);
}.bind(this)}>{data[i].title}</a></li>);
i = i + 1;
}
return (
<nav>
<ul>{lists}</ul>
</nav>
);
}
}
export default TOC;
//TOC.js
while (i < data.length) {
lists.push(<li key={data[i].id}>
<a href={"/content/" + data[i].id}
data-id={data[i].id}
onClick={function (id, e) {
e.preventDefault();
this.props.onChangePage(id);
}.bind(this, data[i].id)}>{data[i].title}</a></li>);
i = i + 1;
}