코딩/리액트

[새싹 성동 2기] 리액트 이벤트 핸들링 사용법과 예시

insu90 2024. 11. 19. 16:56

1. 리액트 이벤트 사용 시 주의사항

#1 이벤트 이름

    • 이벤트 이름은 카멜 케이스로 작성해야 합니다.
      • onclick (x) OnClick (x) onClick (o)
      • onkeyup (x) OnKeyUp (x) onKeyUp (o)
         

#2 이벤트 핸들러

  • JSX에서 이벤트 핸들러는 자바스크립트 코드가 아닌 함수 형태로 전달해야 합니다.
    <button onClick="javascript: alert('hello');"> // (x)
    
    <button onClick={() => alert('hello')}> // (o)   ⇐ 함수를 화살표 함수로 직접 정의
    
    const handleClick = () => alert('hello');
    <button onClick={handleClick}> // (o)   ⇐ 외부에 정의한 함수 이름을 전달
  • 매개변수가 필요한 경우:
    const handleClick = (message) => alert(message);
    <button onClick={() => handleClick("Hello")} />
  • 이벤트 객체의 경우:
    const handleClick = e => alert(e.target.name);
    <button onClick={handleClick} />

#3 DOM 요소만 이벤트 설정 가능

  • HTML 태그에는 이벤트 설정이 가능하지만, 사용자 정의 컴포넌트에는 props로 전달됩니다.
    <div onMouseOver={ () => { ... } } />		⇐ DOM 요소에 이벤트 설정이 가능
    <MyComponent onMouseOver={ () => { ... } } /> 	⇐ 컴포넌트에서는 이벤트 설정을 할 수 없음

2. 이벤트 핸들링 기본 실습

기본 예제: 입력값 출력하기

  1. src 디렉토리에 event 폴더 생성 후, EventPractice.js 파일 작성:
    function EventPractice() {
        return (
            <>
                <h1>이벤트 연습</h1>
            </>
        );
    }
    export default EventPractice;
  2. App.js에서 컴포넌트를 추가:
    import EventPractice from "./event/EventPractice";
    
    
    function App() {
      return (
        <EventPractice />
      );
    }
    
    
    export default App;
  3. EventPractice 컴포넌트에 입력창을 추가하고, 입력값을 콘솔에 출력하도록 수정:
    function EventPractice() {
        return (
            <>
                <h1>이벤트 연습</h1>
                <input type="text" name="message" placeholder="입력해 보세요."
                    onChange={e => console.log(e.target.value)} />
            </>                                ~~~~~~~~~~~~~~ 입력창에 변경된 내용이 반영된 값
        );
    }
    export default EventPractice;
  4. 상태 변수를 추가하고, 입력 내용을 해당 변수에 설정:
    import { useState } from "react";
    
    function EventPractice() {
        const [message, setMessage] = useState('');
    
        return (
            <>
                <h1>이벤트 연습</h1>
                <input type="text" name="message" placeholder="입력해 보세요."
                    onChange={e => setMessage(e.target.value)} />
                <h2>입력창 내용 : {message}</h2>
            </>
        );
    }
    export default EventPractice;
  5. 버튼을 추가하고, 해당 버튼을 클릭하면 입력값과 입력 내용을 제거하도록 수정:
    import { useState } from "react";
    
    function EventPractice() {
        const [message, setMessage] = useState('');
    
        return (
            <>
                <h1>이벤트 연습</h1>
                <input type="text" name="message" placeholder="입력해 보세요."
                    onChange={e => setMessage(e.target.value)}
                    value={message} />				⇐ 해당 코드가 없으면 버튼을 클릭해도 입력창에 내용이 
                <h2>입력창 내용 : {message}</h2>		   사라지지 않는 문제가 있음
                <button onClick={() => setMessage('')}>입력 내용 삭제</button>
            </>
        );
    }
    export default EventPractice;

별도정리: 함수 컴포넌트를 클래스 컴포넌트로 변경하기.

// React의 Component 클래스를 가져옵니다.
import { Component } from "react";

// EventPractice라는 클래스형 컴포넌트를 정의합니다.
class EventPractice extends Component {
    /*
    // (선택적) 이전 방식: 생성자를 사용해 상태를 초기화하고 메서드를 바인딩하는 방식
    constructor(props) {
        super(props); // 부모 클래스인 Component의 생성자를 호출합니다.
        this.state = { // 초기 상태를 정의합니다.
            message: '' // 입력창의 값을 저장할 상태 변수
        };
        this.handleChange = this.handleChange.bind(this); // 메서드 바인딩
    }

    // 입력창에 입력된 값을 상태로 업데이트하는 메서드
    handleChange(e) {
        this.setState({ message: e.target.value });
    }
    */

    // 상태 변수를 정의합니다. 최신 문법을 사용한 방식입니다.
    state = {
        message: '' // 입력창의 내용을 저장할 상태 변수
    };

    // 화살표 함수를 사용해 메서드를 정의합니다.
    // 화살표 함수는 this 바인딩이 필요 없기 때문에 생성자에서 바인딩하지 않아도 됩니다.
    handleChange = e => this.setState({ message: e.target.value });

    // 컴포넌트의 UI를 렌더링하는 메서드
    render() {
        return (
            <>
                {/* 제목 표시 */}
                <h1>이벤트 연습</h1>

                {/* 입력창: 사용자가 입력한 내용을 상태로 저장합니다. */}
                <input 
                    type="text" // 입력창 타입을 텍스트로 설정
                    name="message" // 입력창의 이름 속성 (필요한 경우 참조 가능)
                    placeholder="입력해 보세요." // 사용자가 입력하기 전 표시될 텍스트
                    onChange={this.handleChange} // 입력 값 변경 시 실행할 이벤트 핸들러
                    value={this.state.message} // 입력창의 값을 상태와 동기화
                />

                {/* 입력창에 입력된 내용을 실시간으로 표시 */}
                <h2>입력창 내용 : {this.state.message}</h2>

                {/* 버튼: 클릭하면 입력된 내용을 초기화합니다. */}
                <button 
                    onClick={() => this.setState({ message: '' })} // 상태를 빈 문자열로 설정
                >
                    입력 내용 삭제
                </button>
            </>
        );
    }
}

// EventPractice 컴포넌트를 외부에서 사용할 수 있도록 내보냅니다.
export default EventPractice;

 

3. 여러 입력값 관리하기

입력창 추가

  • 사용자 이름 입력창 추가:
import { useState } from "react";


function EventPractice() {
    const [message, setMessage] = useState('');
    const [username, setUsername] = useState('');


    return (
        <>
            <h1>이벤트 연습</h1>
            <input type="text" name="message" placeholder="입력해 보세요."
                onChange={e => setMessage(e.target.value)}
                value={message} />
            <input type="text" name="username" placeholder="이름을 입력하세요."
                onChange={e => setUsername(e.target.value)}
                value={username} />
            <h2>입력창 내용 : {message}</h2>
            <h2>사용자 이름 : {username}</h2>
            <button onClick={() => {
                setMessage('');
                setUsername('');
            }}>입력 내용 삭제</button>
        </>
    );
}
export default EventPractice;

 

이벤트 핸들러  별도 정의 및 통합

  • 이벤트 핸들러 함수를 별도 정의:
    import { useState } from "react";
    
    
    function EventPractice() {
        const [message, setMessage] = useState('');
        const [username, setUsername] = useState('');
    
    
        const changeMessage = e => setMessage(e.target.value);
        const changeUsername = e => setUsername(e.target.value);
    
    
        return (
            <>
                <h1>이벤트 연습</h1>
                <input type="text" name="message" placeholder="입력해 보세요."
                    onChange={changeMessage} value={message} />
                <input type="text" name="username" placeholder="이름을 입력하세요."
                    onChange={changeUsername} value={username} />
                <h2>입력창 내용 : {message}</h2>
                <h2>사용자 이름 : {username}</h2>
                <button onClick={() => {
                    setMessage('');
                    setUsername('');
                }}>입력 내용 삭제</button>
            </>
        );
    }
    export default EventPractice;
  • 여러 입력값을 하나의 핸들러로 관리:
    import { useState } from "react";
    
    function EventPractice() {
        const [message, setMessage] = useState('');
        const [username, setUsername] = useState('');
    
        const changeInputValue = e => {
            if (e.target.name === "message") {
                setMessage(e.target.value);
            } else if (e.target.name === "username") {
                setUsername(e.target.value);
            }
        }
    
        return (
            <>
                <h1>이벤트 연습</h1>
                <input type="text" name="message" placeholder="입력해 보세요."
                    onChange={changeInputValue} value={message} />
                <input type="text" name="username" placeholder="이름을 입력하세요."
                    onChange={changeInputValue} value={username} />
                <h2>입력창 내용 : {message}</h2>
                <h2>사용자 이름 : {username}</h2>
                <button onClick={() => {
                    setMessage('');
                    setUsername('');
                }}>입력 내용 삭제</button>
            </>
        );
    }
    export default EventPractice;
  • 입력창의 이름을 관리하는 상태 변수를 추가해서 이벤트 핸들러 함수를 하나로 통일:
    // React의 useState를 불러옵니다. 컴포넌트에서 상태를 사용하기 위해 필요합니다.
    import { useState } from "react";
    
    function EventPractice() {
        // 상태를 하나의 객체로 통합하여 관리합니다.
        // form 객체는 입력 필드의 값을 저장하며, 각 필드의 이름(name)을 키로 사용합니다.
        const [form, setForm] = useState({
            message: '', // "message" 입력 필드의 초기값
            username: '' // "username" 입력 필드의 초기값
        });
    
        // 입력값이 변경될 때 호출되는 이벤트 핸들러 함수
        const changeInputValue = e => {
            // setForm을 사용해 form 객체를 업데이트합니다.
            // 스프레드 연산자(...form)는 기존 상태를 복사하여 유지합니다.
            // [e.target.name]: e.target.value 는 변경된 필드만 업데이트합니다.
            setForm({ 
                ...form, // 기존 form 객체를 유지
                [e.target.name]: e.target.value // 입력 필드의 name에 해당하는 값을 업데이트
            });
        }
    
        // form 객체의 값을 각각의 지역 변수로 추출하여 사용합니다.
        // 비구조화 할당을 통해 form.message와 form.username을 message와 username으로 간단히 접근합니다.
        const { message, username } = form;
    
        return (
            <>
                <h1>이벤트 연습</h1>
                
                {/* 첫 번째 입력 필드: 사용자가 입력할 메시지를 처리합니다. */}
                <input 
                    type="text" 
                    name="message" // 필드 이름을 "message"로 설정
                    placeholder="입력해 보세요." // 입력창의 힌트 텍스트
                    onChange={changeInputValue} // 입력값이 변경되면 호출되는 핸들러
                    value={message} // 입력 필드에 표시되는 값은 상태 message에 연결
                />
                
                {/* 두 번째 입력 필드: 사용자의 이름을 처리합니다. */}
                <input 
                    type="text" 
                    name="username" // 필드 이름을 "username"으로 설정
                    placeholder="이름을 입력하세요." // 입력창의 힌트 텍스트
                    onChange={changeInputValue} // 입력값이 변경되면 호출되는 핸들러
                    value={username} // 입력 필드에 표시되는 값은 상태 username에 연결
                />
                
                {/* 입력된 메시지와 이름을 화면에 표시 */}
                <h2>입력창 내용 : {message}</h2>
                <h2>사용자 이름 : {username}</h2>
                
                {/* 버튼을 클릭하면 입력값을 모두 초기화합니다. */}
                <button 
                    onClick={() => {
                        // form 객체를 초기화하여 입력값을 모두 비웁니다.
                        setForm({ message: '', username: '' });
                    }}
                >
                    입력 내용 삭제
                </button>
            </>
        );
    }
    
    export default EventPractice;

 

 

 

 

 

 

 

 

 

 

 

*생성형 AI 활용한 클라우드&보안 전문가 양성캠프 과정의 교육내용 정리 자료입니다.