[React] 컴포넌트 이벤트 만들기(onChangePage)
서론
<header>
<h1><a href='/' onClick={function(e) {
console.log("event in", this)
e.preventDefault();
this.setState({mode : "welcome"});
}.bind(this)}>{this.state.subject.title}</a></h1>
{this.state.subject.sub}
</header>
저번 글에선 위 코드의 <header> 태그를 App.js 컴포넌트에 옮겨 놓았었는데,
이 글에서는 <header> 태그를 주석 처리하고 주석 처리했었던 <Subject> 컴포넌트를 다시 쓰겠다.
이제 Subject 컴포넌트에 <a> 태그를 클릭하면 onChangePage 이벤트를 발생시키는 기능을 만들어보자!
컴포넌트 이벤트 만들기
<Subject
title={this.state.subject.title}
sub={this.state.subject.sub}
onChangePage={function() {
alert("hi");
}.bind(this)}
></Subject>
일단 App 컴포넌트에서 Subject 컴포넌트에 onChangePage 함수를 추가한다.
그리고 테스트용으로 onChangePage 함수는 alert("hi")를 실행하게 된다.
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>
);
}
}
다음 Subject.js를 이 코드로 수정해보자.
Subject 컴포넌트의 <a> 태그를 클릭했을 때(onClick) 함수가 실행되고 인자로 (e)가 전달된다.
또, 저번 글에서 배웠던 preventDefault()로 페이지가 새로고침되는 걸 막는다.
웹을 실행해보면 WEB을 눌렀을 때 "hi"라는 메세지는 잘 뜬다.
하지만 F12를 눌러 확인해보면 사진과 같은 경고 메세지가 뜨는 걸 확인할 수 있고, 페이지도 바뀌지 않는다.
페이지가 바뀌지 않고, 경고 메세지가 뜬 이유는 onChangePage라는 이벤트에 props값을 전달하지 않았기 때문이다.
alert("hi")만 있는 onChangePage 이벤트는 당연히 mode값이 바뀌지 않는다.
Subject.js를 보면 this.props.onChangePage 인 것을 볼 수 있다.
Subject 컴포넌트는 props값을 넘겼으나 onChangePage에서 사용하지 않아 발생한 경고 메세지이다.
그래서 이제 이 props값을 사용하면 된다.
setState 함수를 이용해 mode를 welcome으로 만들면 된다.
웹을 실행해보면 페이지도 바뀌고 경고 메세지도 안 뜨는 걸 확인할 수 있다.
다음 글을 적기 전에 깔끔하게 주석을 지운다.
App.js 최종
import React, { Component } from 'react';
import Subject from './components/Subject';
import TOC from './components/TOC';
import Content from './components/Content';
class App extends Component {
constructor(props) {
super(props);
this.state = {
mode:'read',
subject:{title:'WEB', sub:'World Wide 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;
}
console.log("render", this);
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>
)
}
}
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;