Library | Framework/React

[React] 컴포넌트 이벤트 만들기(onChangePage)

나는김혜린 2022. 1. 5. 05:37

서론

	<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;