[React]생활코딩 4️⃣ - 이벤트
이벤트
리액트는 props, state ,event가 상호작용하면서 애플리케이션을 역동적으로 만들어준다.
리액트에서는 state나 props 값이 바뀌면 그 state를 가지고있는 컴포넌트의 render( )함수가 다시 로드되기 때문에,
그 하위에 있는 컴포넌트들의 render( ) 함수도 다시 호출된다.
따라서, render( ) 함수는 어떤 HTML을 그릴지 결정하는 함수이기 때문에
state나 props 값이 바뀌면 화면이 다시 그려진다.
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',
subject:{title:'WEB', sub:'World Wid Web!'},
welcome:{title:'Welcome', desc:'Hello, React!!'},
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() {
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">
{/* <Subject
title={this.state.subject.title}
sub={this.state.subject.sub}>
</Subject> */}
<header>
<h1><a href="/" onClick={function(e){ //자바스크립트는 onclick, 리액트는 onClick
console.log(e); //=> render( ) 안의 HTML 태그는 순수 HTML이 아니라 유사 HTML이기 때문에 규칙을 따라야한다.
debugger; // 개발자도구의 break point와 같은 역할.
e.preventDefault();
this.setState({
mode:'welcome'
});
}.bind(this)}>{this.state.subject.title}</a></h1>
{this.state.subject.sub}
</header>
<TOC data={this.state.contents}></TOC>
<Content title={_title} desc={_desc}></Content>
</div>
);
}
}
export default App;
- setState( ) : state값을 바꾸는 함수.
- .bind(this) : this.setState에서 this가 가리키는 값이 없기때문에
TypeError: Cannot read property 'state' of undefined
에러가 출력된다.
=> render( ) 함수를 가지고있는 컴포넌트를 this에 담기 위해서 함수에 .bind(this)을 붙여줌.
React의 이벤트 처리하기
React 엘리먼트에서 이벤트를 처리하는 방식은 DOM 엘리먼트에서 이벤트를 처리하는 방식과 매우 유사하다.
몇가지 문법 차이는 다음과 같다.
- React의 이벤트는 소문자 대신 캐멀 케이스를 사용한다.
- JSX를 사용하여 문자열이 아닌 함수로 이벤트 헨들러를 전달한다.
- false를 반환해도 기본 동작을 방지할 수 없기때문에 반드시 preventDefault를 명시적으로 호출해야한다.
예) HTML
<button onclick="activateLasers()">
Activate Lasers
</button>
예) React
<button onClick={activateLasers}>
Activate Lasers
</button>
bind( ) 함수 이해하기
var obj = {name: 'egoing'}
function bindTest() {
console.log(this.name);
}
bindTest(); // undefined
var bindTest2 = bindTest.bind(obj);
bindTest2.bind(obj); // egoing
setState( ) 함수 이해하기
constructor 에서는 아래와 같이 간단하게 state값을 변경할 수 있다.
this.state = {
mode:'read',
subject:{title:'WEB', sub: 'World Wide Web'},
welcome:{titlle:'Welcome', desc:'Hello, React!!'},
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( ) 함수 안에서는 setState( ) 함수로 컴포넌트의 state값을 불러와서 변경 해준다.
컴포넌트 이벤트만들기
App.js) 이벤트를 사용할 곳
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 data={this.state.contents}></TOC>
<Content title={_title} desc={_desc}></Content>
</div>
);
컴포넌트를 사용하는 App.js 에서는 컴포넌트의 속성으로 onChangePage에 function을 준다. onChangePage는 props로 전달된다.
Subject.js)
return (
<header>
<h1><a href="/" onClick={function(e){
e.preventDefault();
this.props.onChangePage();
}.bind(this)}>{this.props.title}</a>
</h1>
{this.props.sub}
</header>
);
컴포넌트를 정의하는 js파일에서는 this.props.onChangePage()로 App.js의 onChangePage를 불러온다.
속성을 이용해서 값을 넘기는 방법
- data-id 라는 props 값은 e.target.dataset.id로 접근해서 넘겨줄 수 있다.
- data-id의 id는 임의로 정할 수 있다
bind() 함수를 이용해서 값을 넘기는 방법
TOC.js)
while (i < data.length) {
list.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;
}
bind()함수의 두번째 인자로 data[i].id 를 주면 bind가 붙은 함수의 첫번째 매개변수로 값을 받는다. 세번째 인자를 주면 그 값은 함수의 두번째 매개변수로 받는다.
Leave a comment