본문 바로가기

Programming/React

React기초- 6.이벤트

반응형

이번 시간에는 클릭 이벤트에 대해 Content가 변경되도록 App을 구성해보겠습니다.

 

1. 아래 화면에서 WEB을 클릭하면 그 아래 HTML / HTML is HyperText Markup Language 부분이 그에 맞는 내용으로 변경되게 할 것입니다.

 

우선 WEB 부분에 해당하는 <h1> 영역에 링크를 달아줍니다.

 

Subject.js

import React, { Component } from 'react';

class Subject extends Component {
    render() {
        return (
            <div>
                <header>
                    <h1><a href="/">{this.props.title}</a></h1>
                    {this.props.sub}
                </header>
            </div>
        );
    }
}

export default Subject;

 

페이지 첫 로딩시와 WEB을 클릭하면 웰컴페이지가 나타나도록 하기 위해 state에 'mode'를 생성하고,

welcome 모드에서 보여줄 내용을 'welcome' 인자를 생성합니다.

render()함수 내부에 _title, _desc 변수를 선언해주고 모드에 따른 내용이 변경되도록 할당해줍니다.

그리고 <Content> 컴포넌트의 내용에 전달되도록 코드를 수정해줍니다.

 

App.js

<Subject> 태그 내부에 onChangePage 속성을 선언하고 실행할 함수를 정의해줍니다. 이 함수는 mode를 'welcome'으로 변경해줍니다.

import React, { Component } from 'react';
import Subject from './components/Subject';
import TOC from './components/TOC';
import Content from './components/Content';
//import logo from './logo.svg'; 삭제
import './App.css';

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      mode: 'read',  // 읽기모드인지 welcome모드인지 구분하는 '모드' 설정
      welcome: { title: 'welcom', desc: 'Hello, React!!' }, // welcome모드에서 표시할 내용 선언
      subject: { title: 'WEB', sub: 'world wide web!' },
      contents: [
        { id: 1, title: 'HTML', desc: 'HTML is HyperText ...' },
        { id: 2, title: 'CSS', desc: 'CSS is for design' },
        { id: 3, title: 'Javascript', desc: 'JavaScript is for interactive' }
      ]
    }
  }
  render() {
    var _title, _desc = null;
    if (this.state.mode === 'welcome') {  // welcome 모드일 경우
      _title = this.state.welcome.title;  // welcome 의 title
      _desc = this.state.welcome.desc;    // welcome 의 desc
    } else if (this.state.mode === 'read') {  // read 모드일 경우
      _title = this.state.contents[0].title;  // 1번째 content의 title: 추후 개선 예정
      _desc = this.state.contents[0].desc;    // 1번째 content의 desc: 추후 개선 예정
    }
    return (
      <div className="App">
        <Subject
          title={this.state.subject.title}
          sub={this.state.subject.sub}
          onChangePage={function () {
            this.setState({ mode: 'welcome' });
          }.bind(this)}
        />

        <TOC data={this.state.contents} />

        <Content title={_title} desc={_desc} /> {/* mode에 따라 타이틀과 desc를 전달받는다. */}
      </div>
    );
  }
}


export default App;

 

Subject.js

<a> 태그 내부에 클릭 이벤트 속성인 onClick으로 onChangePage()함수를 연결해줍니다.

import React, { Component } from 'react';

class Subject extends Component {
    render() {
        return (
            <div>
                <header>
                    <h1><a href="/" onClick={function (e) {
                        e.preventDefault();
                        this.props.onChangePage();
                    }.bind(this)}>{this.props.title}</a></h1>
                    {this.props.sub}
                </header>
            </div>
        );
    }
}

export default Subject;

 

2. 다음으로 HTML / CSS / JavaScript부분을 클릭하면 역시 내용이 변경되도록 해보겠습니다.

 

App.js

<TOC> 태그 내부에 마찬가지로 onChangePage 함수를 선언해줍니다.

import React, { Component } from 'react';
import Subject from './components/Subject';
import TOC from './components/TOC';
import Content from './components/Content';
import './App.css';

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      mode: 'read',
      selected_content_id: 2,  // 기본적으로 2번이 선택되도록 함
      welcome: { title: 'welcom', desc: 'Hello, React!!' },
      subject: { title: 'WEB', sub: 'world wide web!' },
      contents: [
        { id: 1, title: 'HTML', desc: 'HTML is HyperText ...' },
        { id: 2, title: 'CSS', desc: 'CSS is for design' },
        { id: 3, title: 'Javascript', desc: 'JavaScript is for 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') {  // read 모드일 경우
      var i = 0;                                // 반복을 위한 i 변수를 선언하고
      while (i < this.state.contents.length) {    // i 가 content의 요소 갯수만큼 반복하며
        var data = this.state.contents[i];    // i 번째 content를 data 라고 정의한다.
        if (data.id === this.state.selected_content_id) { // data의 id와 현재 선택된 content의 id가 일치할 경우
          _title = data.title;  // content의 title을 다음 진행(출력)으로 넘겨준다.
          _desc = data.desc;    // content의 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)}
        />

        <TOC
          onChangePage={function (id) {         // 몇번째 요소인지를 id로 넘겨받아서 실행한다.
            this.setState({
              mode: 'read',                     // 모드를 read로 바꿔준다.
              selected_content_id: Number(id)   // selected_content_id에 넘겨받은 id값을 할당하면서 숫자형으로 변환한다.
            });
          }.bind(this)}
          data={this.state.contents} />

        <Content title={_title} desc={_desc} />
      </div>
    );
  }
}


export default App;

 

TOC.js

<a> 태그 내부에 onClick 이벤트 함수를 지정해줍니다.

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}       // 몇번째 요소의 이벤트인지를 나타내는 id 
                        			  // 'data-XXX'접두사로 시작하는 속성은 e.target.dataset.XXX으로 접근가능하다.
                        onClick={function (e) {                              
                            e.preventDefault();
                            			  // onChangePage()함수를 연결하면서 id값을 넘겨준다.
                            this.props.onChangePage(e.target.dataset.id);  
                        }.bind(this)}
                    >{data[i].title}</a></li>);
            i = i + 1;
        }
        return (
            <div>
                <nav>
                    <ul>
                        {lists}
                    </ul>
                </nav>
            </div>
        );
    }
}

export default TOC;
반응형

'Programming > React' 카테고리의 다른 글

React기초- 8.Update  (0) 2020.07.29
React기초- 7.Create  (0) 2020.07.29
React기초-5.state2  (0) 2020.07.27
React기초-4.state  (0) 2020.07.25
React기초-3.props  (0) 2020.07.25