본문 바로가기

그 땐 Front했지/그 땐 React했지

[생활코딩/React] 17. 컴포넌트 이벤트

728x90

참고자료: 유튜브 생활코딩 React https://www.youtube.com/playlist?list=PLuHgQVnccGMCRv6f8H9K5Xwsdyg4sFSdi

 

1.  컴포넌트 이벤트 만들기 1


//App.js
return (
  <div className="App">
    <Subject 
      title={this.state.subject.title} 
      sub={this.state.subject.sub}
      onChangePage={function(){
        alert('hihi')
      }.bind(this)}>
    </Subject>
    <TOC
      data={this.state.contents}>
    </TOC>
    <Content 
      title={_title} 
      desc={_desc}>
    </Content>
  </div>
);

👉🏻Subject component에 onChangePage라는 이름의 이벤트를 만들어 props로 전달한다. 이 이벤트를 실행하면 이벤트에 설치한 함수를 호출한다.

//Subject.js
class Subject extends Component {
    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 component에서 onChangePage 이벤트(이벤트가 컴포넌트로 넘어올 때는 함수의 형태)를 호출한다.

👉🏻WEB 글씨를 클릭하면 alert창이 잘 뜬다!

//App.js
<Subject 
  title={this.state.subject.title} 
  sub={this.state.subject.sub}
  onChangePage={function(){
    this.setState({mode:'welcome'});
  }.bind(this)}>
</Subject>

👉🏻이 상태에서 setState함수를 이용해 mode값을 변경시키자!

👉🏻내용이 알맞게 잘 변경되었다!

 

2.  컴포넌트 이벤트 만들기 2


//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}
      onChangePage={function(){
        this.setState({mode:'read'});
      }.bind(this)}>
    </TOC>
    <Content 
      title={_title} 
      desc={_desc}>
    </Content>
  </div>
);

👉🏻TOC에도 같은 이벤트를 설치하되 이번엔 mode값을 read로 설정한다.

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} 
              onClick={function(e){
                e.preventDefault();
                this.props.onChangePage();
              }.bind(this)}>
                {data[i].title}
            </a>
          </li>
        );
        i = i + 1;
      }
      return (
        <nav>
            <ul>
              {lists}
            </ul>
        </nav>
      );
    }
  }

👉🏻TOC.js의 a tag에도 onClick으로 해당 함수를 실행한다. 이렇게 하면 TOC의 li tag 3개중 아무 tag만 눌러도 mode값이 변하면서 내용도 변한다!

 

3.  컴포넌트 이벤트 만들기 3


 

이 상태에서 각 리스트(HTML, CSS, JavaScript)를 클릭하면 아래 내용이 그에 맞는 내용으로 변하게 해보자!
//App.js
this.state = {
  mode: 'read',
  selected_content_id:2,
  subject: {title: "WEB3", sub: "world wide web!3"},
  welcome: {title: "Welcome", desc: "Hello, React!!"},
  contents: [
    {id: 1, title: "HTML3", desc: "HTML is for information.3"},
    {id: 2, title: "CSS3", desc: "CSS is for design.3"},
    {id: 3, title: "JavaScript3", desc: "JavaScript is for interactive.3"},
  ]
}

👉🏻먼저 state에 selected_content_id를 임의의 숫자로 설정해서 추가해준다.

//Subject.js
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}
          onClick={function(e){
            e.preventDefault();
            this.props.onChangePage(e.target.dataset.id);
          }.bind(this)}>
            {data[i].title}
        </a>
      </li>
    );
    i = i + 1;
  }
  return (
  	...중략...
    )
  }

👉🏻a tag에 data-id라는 속성을 통해 해당 리스트의 id값을 저장한다. 그리고 이 id값을 onChangePage의 인자로 넘겨준다.

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

👉🏻받아온 인자를 Number함수를 통해 숫자로 바꿔주고 setState를 통해 selected_content_id를 바꿔준다.

  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') {
      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 (
    	...중략...
    )
}

👉🏻render 부분에 mode가 read일 때 selected_content_id값에 따라 제목과 내용이 바뀌게 하는 코드를 적는다.

  • contents state의 길이만큼 while문을 돌리면서 selected_content_id와 비교한다.
  • 두 값이 같으면 _title과 _desc에 contents state에서 id에 맞는 title, desc 값을 넣어준다.
  • _title, _desc를 Content component의 props로 보내준다.

최종 코드

728x90