Peony의 기록 창고 🌼
article thumbnail
Published 2022. 3. 18. 14:25
[React] 이벤트 핸들링 React
반응형

리액트의 이벤트 시스템

사용자가 웹 브라우저에서 DOM 요소들과 상호 작용하는 것을 이벤트(event)라고 한다. 리액트의 이벤트 시스템은 웹 브라우저의 HTML 이벤트와 인터페이스가 동일하기 때문에 사용법이 꽤 비슷하다.

 

이벤트 사용 시 주의 사항

  1. 이벤트 이름 : 카멜 표기법으로
  2. HTML에서는 onclick 으로 작성하지만 리액트에서는 카멜 표기법으로 onClick 으로 작성해야 한다.
  3. 이벤트에 함수 형태의 값을 전달
  4. HTML에서 이벤트를 설정할 때 큰따옴표 안에 실행할 코드를 넣었지만, 리액트에서는 함수 형태의 객체를 전달한다. 화살표 함수 문법을 사용하거나 혹은 외부에 미리 함수를 만들어서 전달하기도 한다.
  5. DOM 요소에만 이벤트를 설정할 수 있다.
     <MyComponent onClick={doSomething} />
    -> 클릭할 때 doSomething함수를 실행하는게 아니라 이름이 onClickprops 를 컴포넌트에 전달할 뿐이다.
     <div onClick={this.props.onClick}>{/* ... */}</div>
  6. 컴포넌트에 자체적으로 이벤트를 설정할 수는 X, 전달받은 props 를 컴포넌트 내부의 DOM 이벤트로 설정할 수는 있다.
  7. div, button, input, form, span 등의 DOM 요소에는 이벤트를 설정할 수 있지만, 직접 만든 리액트 컴포넌트에는 이벤트를 자체적으로 설정할 수 없다.

 

이벤트 핸들링 예제

컴포넌트 생성 및 불러오기

src 디렉토리에 EventPractice.js 파일을 만들고 App 컴포넌트에서 불러와 렌더링한다.

 //EventPractice.js
 const EventPractice = () => {
   return (
     <div>
       <h1>Event 연습</h1>
     </div>
   );
 };
 ​
 export default EventPractice;
 //App.js
 import './App.css';
 import EventPractice from './EventPractice';
 ​
 ​
 function App() {
   
   return <EventPractice />;
 ​
 };
 ​
 export default App;

 

onChange 이벤트 핸들링하기

 const EventPractice = () => {
     return (
       <div>
         <h1>Event 연습</h1>
         <input 
             type = "text"
             name = "message"
             placeholder = "아무거나 입력해보새요"
             onChange = {
                 (e) => {
                     console.log(e);
                 }
             }
         />
       </div>
     );
   };
   
   export default EventPractice;

여기서 콘솔에 기록되는 e객체는 SyntheticEvent로 웹 브라우저의 네이티브 이벤트를 감싸는 객체이다. 이 이벤트는 네이티브 이벤트와 달리, 이밴트가 끝나고 나면 이벤트가 초기화 되므로 정보를 참조할 수 없다.

만약, 비동기적으로 이벤트 객체를 참조할 일이 있다면 e.persist() 함수를 호출해주어야 한다.

 onChange = {
   (e) => {
     console.log(e.target.value);
   }
 }

 

state에 input값 담기

 /EventPractice.js
 import { useState } from 'react';
 ​
 const EventPractice = () => {
     const [message, setMessage] = useState(' ');
     const onChangeMessage = e => setMessage(e.target.value);
     return (
       <div>
         <h1>Event 연습</h1>
         <input 
             type = "text"
             name = "message"
             placeholder = "아무거나 입력해보새요"
             value = {message}
             onChange = {onChangeMessage}
             
         />
       </div>
     );
   };
   
   export default EventPractice;

 

버튼을 누를 때 comment 값을 공백으로 설정

우리가 입력한 값이 state에 잘 들어갔는디, 인풋에서 그 값을 제대로 반영하는지 검증해보자.

 //EventPractice.js
 import { useState } from 'react';
 ​
 const EventPractice = () => {
     const [message, setMessage] = useState(' ');
     const onChangeMessage = e => setMessage(e.target.value);
     const onClick = () => {
         alert(message);
         setMessage(' ');
     };
     return (
       <div>
         <h1>Event 연습</h1>
         <input 
             (...)
         />
         <button onClick={onClick}> 확인 </button>
       </div>
     );
   };
   
   export default EventPractice;

 

input 여러개 만들기

만약 input이 여러개일때는 어떻게 해야할까? 메서드를 여러개 만드는 것 보다 event 객체를 활용하는 것이 쉽게 처리할 수 있다. e.target.name 값을 사용하려면 useState를 쓸 때, 인풋값이 들어있는 form 객체를 사용해서 처리해주면 된다.

 //EventPractice.js
 import { useState } from 'react';
 ​
 const EventPractice = () => {
     const[form, setForm] = useState({
         username : ' ',
         message : ' '
     });
     const { username, message } = form;
     const onChange = e => {
         const nextForm = {
             ...form, //기존의 form 내용을 이자리에 복사한 뒤
             [e.target.name]: e.target.value // 원하는 값을 덮어 씌우기
         };
         setForm(nextForm);
     };
     const onClick = () => {
         alert(username + ": " + message);
         setForm({
             username:' ',
             message: ' '
         });
     };
 ​
     return (
       <div>
         <h1>Event 연습</h1>
         <input 
             type = "text"
             name = "username"
             placeholder = "사용자명"
             value = {username}
             onChange = {onChange}
         />
         <input 
             type = "text"
             name = "message"
             placeholder = "아무거나 입력해보새요"
             value = {message}
             onChange = {onChange}
         />
         <button onClick={onClick}> 확인 </button>
       </div>
     );
   };
   
   export default EventPractice;

객체 안에서 key를 [ ]로 감싸면 그 안에 넣은 레퍼런스가 가리키는 실제 값이 key 값으로 사용됩니다.

 

onKeyPress 이벤트 핸들링

comment 인풋에서 enter 키를 눌렀을 때, onClick 메서드를 호출하도록 해보자

 //EventPractice.js
 import { useState } from 'react';
 ​
 const EventPractice = () => {
     const[form, setForm] = useState({
         username : ' ',
         message : ' '
     });
     const { username, message } = form;
     const onChange = e => {
         const nextForm = {
             ...form, //기존의 form 내용을 이자리에 복사한 뒤
             [e.target.name]: e.target.value // 원하는 값을 덮어 씌우기
         };
         setForm(nextForm);
     };
     const onClick = () => {
         alert(username + ": " + message);
         setForm({
             username:' ',
             message: ' '
         });
     };
     const onKeyPress = e => {
         if(e.key === 'Enter') {
             onClick();
         }
     };
 ​
     return (
       <div>
         <h1>Event 연습</h1>
         <input 
             type = "text"
             name = "username"
             placeholder = "사용자명"
             value = {username}
             onChange = {onChange}
         />
         <input 
             type = "text"
             name = "message"
             placeholder = "아무거나 입력해보새요"
             value = {message}
             onChange = {onChange}
             onKeyPress = {onKeyPress}
         />
         <button onClick={onClick}> 확인 </button>
       </div>
     );
   };
   
   export default EventPractice;

 

이 글은 김민준 님의 리액트를 다루는 기술을 읽고 정리한 내용입니다.

반응형
profile

Peony의 기록 창고 🌼

@myeongju