import { Component } from 'react';
class Subject extends Component {
render() {
return (
<header>
<h1><a href="/">{this.props.title}</a></h1>
{this.props.sub}
</header>
);
}
}
export default Subject;
this.state = {
mode: "welcome",
welcome: (title: "Welcome", desc: "Hello, React!")
}
render() {
console.log('App 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') {
_title = this.state.contents[0].title;
_desc = this.state.contents[0].desc;
}
return {
<div className="App">
<Context title={_title} desc={_desc}></Context>
</div>
}
}
render()
JS문법
<a href='/' onclick=""></a>
리액트문법
<a href='/' onClick={}></a>
debugger
: 개발자도구 - Sources에서 소스코드 확인하면서 디버그 가능
이벤트 동작 시 자동으로 새로고침을 방지하는 방법 (기본 동작 방지)
preventDefault()
사용하기
<header>
<h1><a href="/" onClick={function(e) {
console.log(e);
e.preventDefault();
}}>{this.state.subject.title}></a></h1>
{this.state.subject.sub}
</header>
이벤트에서 state
변경 방법
this.state.mode = 'welcome';
으로 코딩하면 동작하지 않는다..bind(this)
를 붙인다.this.setState({})
를 사용한다.<header>
<h1><a href="/" onClick={function(e) {
console.log(e);
e.preventDefault();
this.setState({
mode: 'welcome'
})
}.bind(this)}>{this.state.subject.title}></a></h1>
{this.state.subject.sub}
</header>
bind(this)
함수 사용 이유
render함수 안에서
this
는 컴포넌트를 가리키지만, 이벤트에서this
는 아무것도 가리키지 않는다. 따라서 bind()함수로 바인딩해주어야 한다.
setState()
함수 사용 이유
생성자 안에서 state값을 변경하는 것은 가능하다. 하지만 render()함수에서 동적으로 state값을 변경할 때 setState() 함수가 아니라
this.state.mode = 'welcome';
과 같이 코딩하면 리액트는 state값 변경을 인지하지 못해서 렌더링이 되지 않는다. 따라서 state값을 변경하려면 setState() 함수를 이용해서 객체 또는 함수를 전달해야 리액트가 인지하고 렌더링이 된다.
<Subject
title={this.state.subject.title}
sub={this.state.subject.sub}
onChangePage={function() {
this.setState({
mode: 'welcome'
})
}.bind(this)}>
</Subject>
App.js
의 Subject
컴포넌트 영역에 onChangePage
를 이용하여 이벤트 함수 생성onChangePage
이벤트는 Subject
컴포넌트에 props
형태로 전달된다!import { Component } from 'react';
class Subject extends Component {
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;
Subject.js
에서 onClick
으로 이벤트 함수를 생성하고 props
형태로 전달된 onChangePage
함수를 적용한다.import logo from './logo.svg';
import './App.css';
import TOC from "./components/TOC";
import Content from "./components/Content";
import Subject from "./components/Subject";
import { Component } from 'react';
class App extends Component {
constructor(props) {
super(props);
this.state = {
mode: 'read',
// 기본으로 지정하는 id값
selected_content_id: 1,
welcome: {title:'Welcome', desc:'Hello, React!'},
subject:{title:'WEB', sub:'World Wide Web'},
contents:[
{id:1, title:'HTML', desc:'HTML is HyperText Markup Language'},
{id:2, title:'CSS', desc:'CSS is for design'},
{id:3, title:'JavaScript', desc:'JavaScript is for interactive'}
]
}
}
render() {
console.log('App 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') {
// while을 이용한 id값 통제
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) {
this.setState({
// 기본 mode는 read로 해두고, string형식인 id값을 숫자형식으로 변경해준다.
mode: 'read',
selected_content_id: Number(id)
})
}.bind(this)} data={this.state.contents}></TOC>
<Content title={_title} desc={_desc}></Content>
</div>
);
}
}
export default App;
App.js
에서 이벤트 처리를 위한 코드를 작성해준다.import { 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();
// 이벤트의 target 속성은 a링크를 가리키고, target 속성 안의 dataset 속성에는 id값이 있다. id값을 가져오도록 하는 코드 작성.
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
에서 이벤트 함수(e)의 속성 중에는 target
이 있고, target
안에 dataset
이라는 속성이 있다. 그 안에 id
값이 표시된다.onChangePage()
함수 안에 이벤트 함수의 속성에서 id
값을 가져올 수 있도록 하는 코드 e.target.dataset.id
를 넣어준다.bind()
의 매개변수로 하는 이벤트 처리import { 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}
onClick={function(id, e) {
e.preventDefault();
this.props.onChangePage(id);
}.bind(this, data[i].id)}>{data[i].title}</a></li>)
i = i+1;
}
return (
<nav>
<ul>
{lists}
</ul>
</nav>
)
}
}
export default TOC;
onClick
이벤트의 함수 안에서 id
값을 매개변수로 받아서 처리할 수 있게 해준다.bind()
함수 안에도 받아올 id
를 매개변수로 넣어주어야 한다.