2025-08-20 Props와 이벤트 객체 'e' 이해하기

2025. 8. 20. 17:10·TIL

1. 오늘 한 것 (What I Did)

  • Props 전달하는 부분 해부
  • 이벤트 핸들러의 'e' 매개변수 이해

2. 새로 이해한 것 (What I Learned)

Props는 "함수의 인자"와 똑같다!

// 일반 JavaScript 함수
function greet(name, age) {
    return `안녕하세요, ${age}살 ${name}님!`;
}

greet("철수", 25); // 함수 호출 시 인자 전달

// React 컴포넌트 (똑같은 원리!)
function Welcome(props) {
    return <h1>안녕하세요, {props.age}살 {props.name}님!</h1>;
}

// 컴포넌트 사용 시 props 전달
<Welcome name="철수" age={25} />

Props 전달 과정 step by step

// 1단계: 부모 컴포넌트에서 데이터 준비
function App() {
    const userName = "김철수";
    const userAge = 30;
    const isLoggedIn = true;
    
    return (
        <div>
            {/* 2단계: 자식 컴포넌트에 props로 전달 */}
            <UserCard 
                name={userName}      // name이라는 이름으로 전달
                age={userAge}        // age라는 이름으로 전달
                loggedIn={isLoggedIn} // loggedIn이라는 이름으로 전달
            />
        </div>
    );
}

// 3단계: 자식 컴포넌트에서 props 받기
function UserCard(props) {
    // props는 객체 형태로 받아짐:
    // props = {
    //   name: "김철수",
    //   age: 30,
    //   loggedIn: true
    // }
    
    return (
        <div>
            <h2>{props.name}</h2>  {/* props.name으로 접근 */}
            <p>나이: {props.age}</p>
            <p>상태: {props.loggedIn ? "로그인됨" : "로그아웃됨"}</p>
        </div>
    );
}
 

구조 분해 할당으로 더 깔끔하게

// 방법 1: props 객체 그대로 받기
function UserCard(props) {
    return <h1>{props.name}</h1>;
}

// 방법 2: 구조 분해 할당 (더 많이 사용)
function UserCard({ name, age, loggedIn }) {
    // 이제 props. 없이 직접 사용 가능!
    return (
        <div>
            <h2>{name}</h2>
            <p>나이: {age}</p>
            <p>상태: {loggedIn ? "로그인됨" : "로그아웃됨"}</p>
        </div>
    );
}
 

Props 전달 다양한 방법들

function App() {
    const user = {
        name: "홍길동",
        age: 25,
        email: "hong@example.com"
    };
    
    const colors = ["red", "blue", "green"];
    
    return (
        <div>
            {/* 문자열 전달 */}
            <Component title="안녕하세요" />
            
            {/* 숫자 전달 (중괄호 필요!) */}
            <Component count={42} />
            
            {/* 변수 전달 */}
            <Component userName={user.name} />
            
            {/* 객체 전달 */}
            <Component user={user} />
            
            {/* 배열 전달 */}
            <Component colors={colors} />
            
            {/* 불린값 전달 */}
            <Component isVisible={true} />
            <Component isHidden />  {/* true와 같음 */}
            
            {/* 함수 전달 */}
            <Component onSave={() => console.log("저장됨")} />
        </div>
    );
}

function Component({ title, count, userName, user, colors, isVisible, onSave }) {
    return (
        <div>
            <h1>{title}</h1>
            <p>카운트: {count}</p>
            <p>사용자: {userName}</p>
            <p>이메일: {user.email}</p>
            <p>첫 번째 색: {colors[0]}</p>
            {isVisible && <span>보임!</span>}
            <button onClick={onSave}>저장</button>
        </div>
    );
}

'e'는 이벤트 객체! React가 자동으로 전달해줌

function InputExample() {
    function handleChange(e) {
        // e는 이벤트 객체 - React가 자동으로 전달
        console.log("이벤트 객체:", e);
        console.log("입력된 값:", e.target.value);
        console.log("이벤트 타입:", e.type); // "change"
        console.log("발생한 요소:", e.target); // input 요소
    }
    
    function handleClick(e) {
        console.log("클릭 위치 X:", e.clientX);
        console.log("클릭 위치 Y:", e.clientY);
        console.log("클릭된 요소:", e.target);
    }
    
    return (
        <div>
            {/* React가 자동으로 이벤트 객체를 handleChange에 전달 */}
            <input onChange={handleChange} />
            <button onClick={handleClick}>클릭</button>
        </div>
    );
}

 

이벤트 객체 안에 뭐가 들어있나?

function EventAnalyzer() {
    function handleInputChange(e) {
        console.log("=== 이벤트 객체 분석 ===");
        
        // 가장 중요한 것들
        console.log("입력값:", e.target.value);     // 현재 입력값
        console.log("요소 이름:", e.target.name);   // input의 name 속성
        console.log("요소 타입:", e.target.type);   // input의 type 속성
        
        // 키보드 이벤트에서 유용한 것들
        console.log("눌린 키:", e.key);            // 어떤 키가 눌렸는지
        console.log("Ctrl 키:", e.ctrlKey);        // Ctrl 키가 눌려있는지
        console.log("Shift 키:", e.shiftKey);      // Shift 키가 눌려있는지
    }
    
    function handleSubmit(e) {
        e.preventDefault(); // 기본 동작 막기 (페이지 새로고침 방지)
        console.log("폼 제출 처리");
    }
    
    return (
        <form onSubmit={handleSubmit}>
            <input 
                name="username"
                type="text"
                onChange={handleInputChange}
                onKeyDown={handleInputChange}
            />
            <button type="submit">제출</button>
        </form>
    );
}
 

이벤트 객체 없이 쓸 때 vs 있을 때

function ComparisonExample() {
    const [count, setCount] = useState(0);
    const [message, setMessage] = useState('');
    
    // 이벤트 객체가 필요 없는 경우
    function simpleClick() {
        setCount(count + 1); // 단순히 count만 증가
    }
    
    // 이벤트 객체가 필요한 경우
    function inputChange(e) {
        setMessage(e.target.value); // 입력값이 필요하므로 e.target.value 사용
    }
    
    function keyPress(e) {
        if (e.key === 'Enter') {  // 어떤 키가 눌렸는지 확인 필요
            console.log("엔터 키 눌림!");
        }
    }
    
    return (
        <div>
            {/* 이벤트 객체 필요 없음 */}
            <button onClick={simpleClick}>카운트: {count}</button>
            
            {/* 이벤트 객체 필요함 */}
            <input 
                value={message}
                onChange={inputChange}    // e.target.value 필요
                onKeyDown={keyPress}      // e.key 필요
            />
        </div>
    );
}
 

이벤트 객체와 다른 인자를 함께 사용하기

function AdvancedExample() {
    function handleDelete(id, e) {
        e.stopPropagation(); // 이벤트 버블링 방지
        console.log(`${id}번 항목 삭제`);
    }
    
    function handleSave(formData, e) {
        e.preventDefault(); // 기본 폼 제출 방지
        console.log("저장할 데이터:", formData);
    }
    
    return (
        <div>
            {/* 이벤트 객체와 다른 인자를 함께 전달 */}
            <button onClick={(e) => handleDelete(123, e)}>
                삭제
            </button>
            
            <form onSubmit={(e) => handleSave({name: "test"}, e)}>
                <button type="submit">저장</button>
            </form>
        </div>
    );
}

3. 실전 예제 - Props와 이벤트를 함께

// 부모 컴포넌트
function TodoApp() {
    const [todos, setTodos] = useState([
        { id: 1, text: "공부하기", done: false }
    ]);
    
    // 자식에게 전달할 함수들
    function handleToggle(id) {
        setTodos(todos.map(todo =>
            todo.id === id ? { ...todo, done: !todo.done } : todo
        ));
    }
    
    function handleDelete(id) {
        setTodos(todos.filter(todo => todo.id !== id));
    }
    
    return (
        <div>
            {todos.map(todo => (
                <TodoItem
                    key={todo.id}
                    todo={todo}              // 객체 prop 전달
                    onToggle={handleToggle}  // 함수 prop 전달
                    onDelete={handleDelete}  // 함수 prop 전달
                />
            ))}
        </div>
    );
}

// 자식 컴포넌트
function TodoItem({ todo, onToggle, onDelete }) {
    // 이벤트 핸들러들
    function handleToggleClick() {
        onToggle(todo.id); // 부모의 함수 호출
    }
    
    function handleDeleteClick(e) {
        e.stopPropagation(); // 이벤트 버블링 방지
        onDelete(todo.id);   // 부모의 함수 호출
    }
    
    return (
        <div onClick={handleToggleClick}>
            <span style={{
                textDecoration: todo.done ? 'line-through' : 'none'
            }}>
                {todo.text}
            </span>
            <button onClick={handleDeleteClick}>삭제</button>
        </div>
    );
}

 

Props 이해하기

  1. Props = 함수의 인자: 부모가 자식에게 데이터 전달하는 방법
  2. 전달: <Component name="값" age={숫자} />
  3. 받기: function Component({ name, age }) { ... }

이벤트 객체 'e' 이해하기

  1. 자동 전달: React가 이벤트 핸들러에 자동으로 전달
  2. 주요 속성: e.target.value, e.key, e.preventDefault()
  3. 선택적 사용: 필요할 때만 매개변수로 받으면 됨
저작자표시 비영리 변경금지 (새창열림)
'TIL' 카테고리의 다른 글
  • JavaScript 공식 문서 읽기 1일 차
  • React에서 HTML input 속성을 활용한 실시간 유효성 검증 구현
  • 2025-08-19 React 공식 문서 - 상호작용 더하기
  • 2025-08-18 React 공식 문서 - UI 표현하기
한비(BIBI)
한비(BIBI)
IT 업계에서 오랫동안 일 하고 싶습니다. 가능하다면 죽을 때까지 배우며 살고 싶습니다. 마케팅과 CX 분야에서 커리어를 쌓았습니다. 지금은 IT 업계에 더 깊이 있게 기여하고자 개발 공부를 하고 있습니다. 이 배움의 여정을 글로 남기고 싶어 블로그를 시작했습니다.
  • 한비(BIBI)
    0과 1로된 세상
    한비(BIBI)
  • 전체
    오늘
    어제
    • 분류 전체보기 (33)
      • 크래프톤 정글 (5)
      • Computer Science (10)
      • 읽고 쓰고 생각하기 (1)
      • 일하면서 배웁니다 (1)
      • TIL (15)
  • 링크

    • LinkedIn
    • Threads
    • Twitter
  • 인기 글

  • 태그

    나만무프로젝트
    운영체제구조
    정글후기
    크래프톤정글
    CPU스케줄링
    컴퓨터과학입문
    데이터시각화
    시스템설계
    gpt인프라
    뉴스피드시스템
  • hELLO· Designed By정상우.v4.10.4
한비(BIBI)
2025-08-20 Props와 이벤트 객체 'e' 이해하기
상단으로

티스토리툴바