본문 바로가기
Language/React

[React] 컴포넌트 이벤트 만들기 - 3

by 며루치꽃 2020. 12. 22.

이번에는 클릭한 Content가 본문에 표시되게 하려고 합니다. 

Content가 여러개 있기 때문에 App의 state에다가 id를 줘서 우리가 현재 선택된 Content를 표시하려고 합니다. id 값을 통해 일치하는 것을 통해 표시하려고 합니다. 

 

만약 data의 id 값과 this.state.selected_content_id 가 일치하게 된다면 Content가 바뀌게 하겠습니다.

우선 constructor(생성자) 부분에 selected_content_id 부분을 지정해주고 

TOC가 리스트이니까, onChanegePage 이벤트가 발생했을때 this.setState를 통해 mode 의 값과 함께 selected_content_id를 지정하도록 하면 됩니다. 

 

App.js

import React, { Component } from "react";
import TOC from "./components/TOC";
import Subject from "./components/Subject";
import Content from "./components/Content";

class App extends Component {
    constructor(props) {
        //
        super(props);
        this.state = {
            mode: "read",
            selected_content_id:2,
            subject: { title: "Web", sub: "world wide web" },
            welcome: { title: "Welcome", desc: "Hello React!!" },
            contents: [
                { id: 1, title: "HTML", desc: "HTML is..." },
                { id: 2, title: "CSS", desc: "CSS is..." },
                { id: 3, title: "JS", desc: "JS is..." },
            ],
        };
    }

    render() {
        var _title,
            _desc = null;
        if (this.state.mode === "welcome") {
            // 만약 현재 state가
            _title = this.state.welcome.title; // this.state의 welcome title이다.
            _desc = this.state.welcome.desc;
        } else if (this.state.mode === "read") {
            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 // Subject라는 컴포넌트에
                    title={this.state.subject.title}
                    sub={this.state.subject.sub}
                    onChangePage={function () {
                        // onChangePage를 만들어서 사용자에게 제공했습니다.
                        this.setState({ mode: "welcome" });
                    }.bind(this)}
                ></Subject>
                {/* <header>
                    <h1><a href="/" onClick={function(e){
                        e.preventDefault();
                        //this.state.mode = 'welcome'
                        this.setState({
                            mode:'welcome'
                        });
                    }.bind(this)}>{this.state.subject.title}</a></h1>
                    {this.state.subject.sub}
                </header> */}
                <TOC
                    onChangePage={function () {
                        this.setState({
                        mode:'read',
                        selected_content_id: 0
                    });
                    }.bind(this)}
                    data={this.state.contents}
                ></TOC>
                <Content title={_title} desc={_desc}></Content>
            </div>
        );
    }
}

export default App;

 

이벤트를 실행시키는 부분은, TOC의 onChangePage에서 이벤트를 실행시켰을 때, App의 TOC에 있는 함수를 실행시키는데, 그것을 실행할때 인자로 우리가 클릭한, 그 항목의 id 값을 주면 될 것 입니다. 

이벤트 객체 중에 target이라는 속성이 있는데, 이벤트가 발생한 태그를 가리킵니다. 

<a
  href={"/content/" + data[i].id}
  data-id={data[i].id}
  onClick={function(e){
  	e.preventDefault();
  	// console.log(e.target);
  	this.props.onChangePage(e.target.dataset.id);
  }.bind(this)}
>
{data[i].title}</a>

 

예를 들어, a 태그 내부에 onCLick 이벤트가 있을 때 이 떄의 이벤트 객체 e.target을 출력하면 이벤트가 발생한 a 태그를 가르키게 됩니다. 

'data-속성명'은 dataset 을 통해 접근할 수 있는데 이때 - 뒤에있는 속성을 클릭하게 되면 해당 속성의 값을 볼 수 있습니다. 

onClick이라는 속성을 이벤트를 실행시킬 때, e.target.dataset.id 을 통해 id의 값을 추출해냅니다. 

 

<TOC
	onChangePage={function (id) {
		this.setState({
        mode:'read',
        selected_content_id: Number(id)
	});
	}.bind(this)}
	data={this.state.contents}
></TOC>

 

클릭했을 때 id의 값이 넘어오고 selected_content_id 의 값을 넘어온 id 값으로 지정해준다면 클릭했을 때 id 값에 따라 Content가 바뀌게 됩니다. 

댓글