[React] - 리액트의 이벤트

Jeonghwan Kim·2022년 12월 18일
0

React

목록 보기
4/6

부스트코스 강의 웹 프론트엔드 시작하기 (리액트&리덕스)
중 'Ch3 리액트의 이벤트'를 정리한 내용이다.

이벤트, state, props, render 함수

  • event는 앱의 역동성을 만들어준다. 제목에 링크를 연결하고 그 링크를 클릭하면 welcome 메세지가 나오게 하고, 그 후 목차에 있는 것들을 클릭하면 클릭한 것의 컨텐츠가 본문에 출력되도록 만들어본다.

  • 먼저 현재 페이지가 welcome페이지인지 읽기 페이지인지 구분하기 위해 state에 mode라는 값을 추가한다.

  • 리액트에서는 state의 값이 바뀌면 그 state를 가지고 있는 컴퍼넌트의 render 함수가 다시 호출된다. 그 render 함수 하위의 컴퍼넌트들도 각각 render 함수가 호출되며 화면이 다시 그려진다.

  • render는 어떤 html을 그릴 것인가를 결정하는 함수이다.

  • props나 state의 값이 바뀌면 해당되는 컴퍼넌트의 render함수가 호출되도록 약속되어 있다 (화면이 다시 그려진다).

  • mode의 값에 따라 컴퍼넌트의 rendering 결과가 달라지게 render 함수에 조건문을 사용해준다. this.state.mode의 값이 welcome일 경우와 read일 경우를 구분해주었다.

  • 그리고 Content 컴퍼넌트의 텍스트로 하드코딩 되어있는 부분도 _title, _desc로 바꾸어 welcome을 화면에 표시해준다.


이벤트 설치

  • event programming을 리액트에서 어떻게 할지 살펴본다.

  • < Subject> 컴퍼넌트안에 있는 링크를 클릭했을 때 < Subject> 바깥의 앱의 state를 변경하는 작업을 해본다.

  • 먼저 < Subject> 컴퍼넌트의 내용을 App에 먼저 도입해서 < a>라는 링크를 클릭할 때 코드가 경고창이 뜨도록 onClick을 사용해 이벤트를 구현한다.

    • 이렇게 하면 실행되지만 ok를 누르면 페이지가 리로드되므로 이를 막기 위해 < a>태그를 클릭했을 때 href 속성이 가리키는 페이지로 이동하는 기본적인 동작방법을 막아야한다.
  • 리액트는 onClick 이벤트가 실행될 때 함수의 첫번째 매개변수의 값으로 이벤트 객체 'e'를 주입해야한다.

    • chrome 개발자 도구에서는 "debugger"라는 코드를 만나면 브라우저는 그 부분에서 실행을 멈추고 sources라는 페이지로 이동해 정보들을 보기 쉽게 해준다. 링크를 클릭하면 실행이 멈추고 기다리고 있는 상태가 된다. function의 첫번째 인자 'e'는 바로 이벤트를 핸들링할 수 있도록 주입되는 정보이다.
    • 'e.preventDefault()'함수는 'e'라는 객체에 속해있고, 이 함수는 이벤트가 발생한 태그가 기본적인 동작방법을 못하게 막는다. < a>태그의 기본적인 동작방법을 금지시킬 수 있다. 이렇게 하면 링크를 클릭할 때마다 e가 어떤 정보가 있는지 console에 출력되고 preventDefault()함수를 통해 페이지가 이동되지 않도록 수정된다.

이벤트에서 state 변경하기

  • state를 세팅한 작업과 event를 설치한 작업을 연결시킨다.

  • 단순히 this.state.mode='welcome';을 추가해주면 에러가 발생하는데, 에러 발생에 두 가지 이유가 있다.
    1) 이벤트가 호출될 때 실행되는 함수 안에서 'this'의 값은 컴퍼넌트 자기자신을 가르키지 않고 아무 값도 세팅되어 있지 않기 때문이다. event를 설치할 때 'this'의 값을 찾을 수 없어서 에러가 발생하면 함수가 끝난 직후에 'bind(this)'를 추가해주면 된다. 'bind(this)'를 추가하면 함수 안에서 this는 컴퍼넌트 자신을 가리키게 된다.

    2) 리액트는 state의 값이 바뀐 사실을 모른다. 'this.state.~'가 아닌 'this.setState()'함수를 사용해야한다. 'this.setState()'함수를 호출할 때 mode를 welcome을 바꾸도록 수정한다.


이벤트 bind 함수 이해하기

  • bind()라는 함수는 실행하는 함수가 끝난 뒤에 붙여주고, 코드에서 onClick 이벤트에 bind(this)를 해주면 < APP> 컴퍼넌트 자체를 가르키는 객체를 그 함수 안으로 주입해서 이 함수 안에서 this는 그 객체가 되게 하는 것이다.

이벤트-setState 함수 이해하기

  • state값을 직접 변경하면 안되고 setState()함수를 통해 변경해야하는 이유를 알아보도록한다.

  • 처음 constructor()함수로 컴퍼넌트 생성이 끝난 다음에 동적으로 state의 값을 바꿀 때는 this.setState()라는 함수에 변경하고 싶은 값을 객체 형태로 넣어주어야한다. 그냥 바꿔주면 리액트 입장에서는 값이 바뀐 사실을 모르게 되기 때문이다.

  • 항상 state값이 변경되면 setState()함수를 이용해서 바꿔야한다. constructor()함수에서는 상관없이 그냥 바꿔주어도 된다.


컴포넌트 이벤트 만들기 1

  • 기존 코드는 < a>태그를 클릭했을 때 onClick 이벤트의 함수가 호출되며 < APP> 컴퍼넌트의 mode 값을 'welcome'으로 바꾸었는데 이번에는 < Subject> 컴퍼넌트 안에 onChangePage라는 이벤트를 만들어 이 컴퍼넌트 안에서 링크를 클릭했을 때 이 이벤트에 설치된 함수를 호출하도록 만드는 작업을 해준다.

  • < Subject> 컴퍼넌트에 onChangePage라는 이벤트를 만들어주고, < Subject> 컴퍼넌트는 페이지가 바뀔 때 컴퍼넌트의 사용자가 설정한 onChangePage 함수를 호출해주면 된다. onChangePage라고 하는 함수는 props 형태로 < Subject>에 전달된다.

  • 링크를 클릭하여 onClick 이벤트가 발생할 때 함수가 실행된다. 함수가 실행될 때 첫번째 인자로 이벤트 인자가 전달되고, 'e'객체의 preventDefault()함수를 호출해 링크를 클릭했을 때 페이지가 바뀌는 것을 막는다. 이후 < Subject>컴퍼넌트의 onChangePage()함수를 호출한다.

  • < Subject> 컴퍼넌트에 onChangePage 라는 이벤트를 만들고 그 안에 함수를 설치했고, 이제 onChangePage 이벤트가 발생할 때 props로 전달되는 onChangePage()함수를 호출하면 된다.

  • 마지막으로 onChangePage()함수가 < APP> 컴퍼넌트의 mode값을 welcome으로 바뀌도록 수정한다.


컴포넌트 이벤트 만들기 2

  • 이번에는 글 목록을 클릭했을 때 < APP>컴퍼넌트의 state 'mode'를 'read'로 바꾸고 클릭한 글 목록에 해당하는 contents 내용이 본문에 나오도록 만들어본다.

  • < TOC> 컴퍼넌트에 onChangePage 이벤트를 생성하고 < TOC> 컴퍼넌트 안에서 props형태로 전달받게 만든다.

    • < TOC> 컴퍼넌트 안에 각각의 목록에 해당하는 < li> 부분에 링크를 클릭했을 때 onClick 이벤트가 실행된다. 이벤트가 실핼될 때 페이지가 바뀌지 않도록 e.preventDefault()함수를 넣어주었고, this.props.onChangePage(); 가 props 형태로 onChangePage()함수를 실행시켜 정상적으로 작동하게 된다.

컴포넌트 이벤트 만들기 3

  • 이어서 클릭한 컨텐츠가 본문에 표시되게 해준다.

  • < App> 컴퍼넌트의 state에 selected_content_id와 같은 이름으로 우리가 현재 선택된 content를 표시한다. 그 값으로 contents라는 객체에 있는 id값과 일치하는 selected_content_id 값과 일치하는 것을 본문에 표시한다.

  • 반복문을 수행하며 현재 순번의 contetns의 data.id 값과 this.state.selected_content_id 값이 일치하는 경우 _title, _desc에 해당되게 해준다.

  • < TOC> 컴퍼넌트의 onChangePage 이벤트를 실행시키는 부분은 TOC.js에서 a태그의 onclick 이벤트가 발생했을 때 this.props.onChangePage()를 실행할 때 App.js의 onChangePage()함수를 실행시키는 것이다. 이 onChangePage()함수를 실행시킬 때 항목의 id값을 넘겨주도록 한다. < TOC> 컴퍼넌트의 a태그에 "data-id={data[i].id}" 속성을 주고 로드하면 해당 id값인 1,2,3을 확인할 수 있다.

    • 이 a태그에서 onClick 이벤트가 발생했을 때 console에 e를 입력하면 e라는 객체가 어떤 정보인지 알 수 있다. 그 중 target이라는 속성이 이벤트가 발생한 태그를 가리키는데, 이를 통해 a태그를 알아내고 이 안의 'data-id' 값을 구할 수 있다. 'data-'로 시작되는 속성은 'dataset'에서 접근할 수 있다.
    • e 객체의 target 속성에서 dataset의 id에 해당하는 값이 data-id가 되는것으로, 이 정보를 onChangePage()함수를 호출하는 코드에 인자로 넣어준다.
  • onChangePage에 id라는 매개변수를 주고 이 id 값을 selected_content_id의 값으로 넣어준다. 이 때 넘어오는 데이터는 숫자형으로 바꿔주기 위해 Number()를 이용해준다.

  • 속성을 이용하지 않고 하는 방법도 있는데, bind(this)의 두번째 인자로 data[i].id 값을 주면 onClick 이벤트에서 실행되는 함수의 첫번째 매개변수 값이 bind의 두번째 인자로 들어온 data[i].id가 된다.

    //TOC.js
    <li key={data[i].id}>
         <a 
             href={"/content/"+data[i].id}
             data-id={data[i].id}
             onClick={function(id,e){
                e.preventDefault();
                this.props.onChangePage(id);
             }.bind(this,data[i].id )}
         >{data[i].title}</a>
    </li>
    
  • 이렇게 하면 링크를 클릭할 때 마다 아래 본문의 컨텐츠가 변경되어 나타난다.

0개의 댓글