[TIL] React 초급: 이벤트

minami·2021년 5월 31일
0

React

목록 보기
3/12

8. 이벤트

8-1. state와 props

import { Component } from 'react';

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

  export default Subject;
  • 이벤트를 설치하기 전에 이벤트를 설치할 컴포넌트를 수정해준다.
this.state = {
	mode: "welcome",
	welcome: (title: "Welcome", desc: "Hello, React!")
}

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;
    }
    return {
        <div className="App">
            <Context title={_title} desc={_desc}></Context>
        </div>
	}
}
  • render()
    • state의 값이나 props의 값이 바뀌면 해당 컴포넌트의 render() 함수가 호출된다. = 화면이 다시 그려진다!
    • 여기에서는 state의 mode 값에 따라 화면을 달라지게 할 수 있다.

8-2. 이벤트 설치

  • JS문법

    <a href='/' onclick=""></a>
  • 리액트문법

    <a href='/' onClick={}></a>
  • debugger: 개발자도구 - Sources에서 소스코드 확인하면서 디버그 가능

  • 이벤트 동작 시 자동으로 새로고침을 방지하는 방법 (기본 동작 방지)

    • preventDefault() 사용하기

      <header>
          <h1><a href="/" onClick={function(e) {
                      console.log(e);
                      e.preventDefault();
          }}>{this.state.subject.title}></a></h1>
          {this.state.subject.sub}
      </header>
  • 이벤트에서 state 변경 방법

    • 리액트는 JS와 다르게 바로 this.state.mode = 'welcome';으로 코딩하면 동작하지 않는다.
    1. 함수 끝에 .bind(this)를 붙인다.
    2. 함수 안에서 this.setState({})를 사용한다.
    <header>
        <h1><a href="/" onClick={function(e) {
                    console.log(e);
                    e.preventDefault();
                    this.setState({
                    	mode: 'welcome'
                    })
        }.bind(this)}>{this.state.subject.title}></a></h1>
        {this.state.subject.sub}
    </header>

8-3. 이벤트에서 사용하는 함수 이해하기

1. bind() 함수

  • bind(this)함수 사용 이유

    render함수 안에서 this는 컴포넌트를 가리키지만, 이벤트에서 this는 아무것도 가리키지 않는다. 따라서 bind()함수로 바인딩해주어야 한다.

2. setState() 함수

  • setState()함수 사용 이유

    생성자 안에서 state값을 변경하는 것은 가능하다. 하지만 render()함수에서 동적으로 state값을 변경할 때 setState() 함수가 아니라 this.state.mode = 'welcome';과 같이 코딩하면 리액트는 state값 변경을 인지하지 못해서 렌더링이 되지 않는다. 따라서 state값을 변경하려면 setState() 함수를 이용해서 객체 또는 함수를 전달해야 리액트가 인지하고 렌더링이 된다.

8-4. 컴포넌트에 이벤트 적용하기

<Subject
	title={this.state.subject.title}
	sub={this.state.subject.sub}
	onChangePage={function() {
		this.setState({
            mode: 'welcome'
        })
	}.bind(this)}>
</Subject>
  • App.jsSubject컴포넌트 영역에 onChangePage를 이용하여 이벤트 함수 생성
    • onChangePage이벤트는 Subject컴포넌트에 props형태로 전달된다!
import { Component } from 'react';

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

  export default Subject;
  • Subject.js에서 onClick으로 이벤트 함수를 생성하고 props형태로 전달된 onChangePage함수를 적용한다.

1. 속성을 이용한 이벤트 처리

import logo from './logo.svg';
import './App.css';
import TOC from "./components/TOC";
import Content from "./components/Content";
import Subject from "./components/Subject";
import { Component } from 'react';

class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      mode: 'read',
      // 기본으로 지정하는 id값
      selected_content_id: 1,
      welcome: {title:'Welcome', desc:'Hello, React!'},
      subject:{title:'WEB', sub:'World Wide Web'},
      contents:[
        {id:1, title:'HTML', desc:'HTML is HyperText Markup Language'},
        {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') {
      // while을 이용한 id값 통제
      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
            title={this.state.subject.title}
            sub={this.state.subject.sub}
            onChangePage={function() {
              this.setState({
                mode: 'welcome'
              })
            }.bind(this)}>
          </Subject>
          <TOC
            onChangePage={function(id) {
              this.setState({
                // 기본 mode는 read로 해두고, string형식인 id값을 숫자형식으로 변경해준다.
                mode: 'read',
                selected_content_id: Number(id)
              })
            }.bind(this)} data={this.state.contents}></TOC>
          <Content title={_title} desc={_desc}></Content>
      </div>
    );
  }
}

export default App;
  • App.js에서 이벤트 처리를 위한 코드를 작성해준다.
import { 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}
                onClick={function(e) {
                  e.preventDefault();
                  // 이벤트의 target 속성은 a링크를 가리키고, target 속성 안의 dataset 속성에는 id값이 있다. id값을 가져오도록 하는 코드 작성.
                  this.props.onChangePage(e.target.dataset.id);
                }.bind(this)}>{data[i].title}</a></li>)
            i = i+1;
        }
      return (
        <nav>
            <ul>
                {lists}
            </ul>
        </nav>
      )
    }
  }

  export default TOC;
  • TOC.js에서 이벤트 함수(e)의 속성 중에는 target이 있고, target 안에 dataset이라는 속성이 있다. 그 안에 id값이 표시된다.
  • onChangePage()함수 안에 이벤트 함수의 속성에서 id값을 가져올 수 있도록 하는 코드 e.target.dataset.id를 넣어준다.

2. bind()의 매개변수로 하는 이벤트 처리

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

  export default TOC;
  • onClick이벤트의 함수 안에서 id값을 매개변수로 받아서 처리할 수 있게 해준다.
  • bind()함수 안에도 받아올 id를 매개변수로 넣어주어야 한다.
profile
함께 나아가는 개발자💪

0개의 댓글