[개념] React에서 이벤트 처리하기

posinity·2023년 3월 11일
0

React

목록 보기
36/58
post-custom-banner

React의 이벤트는 소문자 대신 캐멀 케이스(camelCase)를 사용합니다.
JSX를 사용하여 문자열이 아닌 함수로 이벤트 핸들러를 전달하거나, 익명 함수를 사용한다
예를 들어, HTML은 다음과 같습니다.

<button onclick="activateLasers()">
  Activate Lasers
</button>

React에서는 약간 다릅니다.

<button onClick={activateLasers}>
  Activate Lasers
</button>

또 다른 차이점으로, React에서는 false를 반환해도 기본 동작을 방지할 수 없습니다. 반드시 preventDefault를 명시적으로 호출해야 합니다. 예를 들어, 일반 HTML에서 폼을 제출할 때 가지고 있는 기본 동작을 방지하기 위해 다음과 같은 코드를 작성할 수 있습니다.

<form onsubmit="console.log('You clicked submit.'); return false">
  <button type="submit">Submit</button>
</form>

React에서는 다음과 같이 작성할 수 있습니다.

function Form() {
  function handleSubmit(e) {
    e.preventDefault();
    console.log('You clicked submit.');
  }

  return (
    <form onSubmit={handleSubmit}>
      <button type="submit">Submit</button>
    </form>
  );
}

DOM 요소에만 이벤트 설정이 가능합니다. div, button, input, form, span 등의 DOM 요소에는 이벤트 설정이 가능하지만, 리액트의 컴포넌트에는 불가능합니다. 예를 들면 위와 같이 button이라는 DOM 요소에 이벤트를 설정했는데, 아래처럼 라는 리액트 컴포넌트에는 onClick을 달아서 우리가 의도한대로 이벤트가 실행되지 않습니다. 그냥 color, name과 같은 props를 전달해주는 것에 불과합니다.

function App() {
  const sayHi = function () {
    alert('hello');
  }
  return (
    <>
      <Component onClick={sayHi} name="홍길동" nickname="홍홍" />
    </>
  );
}

이벤트 객체

const App = () => {
    const handleChange = (event) => {
      console.log(event.target.value + "라고 입력하셨네요.");
    }
    return (
    <div>
      <input onChange={handleChange} />
    </div>
    );
};

DOM Element의 경우 핸들링 함수에 이벤트 object를 매개변수로 전달한다.
이벤트 object를 이용하여 이벤트 발생 원인, 이벤트가 일어난 Element에 대한 정보를 얻을 수 있다.
이벤트 형태(클릭, 키 입력 등)와 DOM 종류(button, form, input 등)에 따라 전달되는 이벤트 object의 내용도 다르니 유의할 것.

컴포넌트 내 이벤트 처리

DOM 버튼 클릭

const App = () => {
    const handleClick = () => {
        alert("클릭했습니다.");
    }
    return (
        <div>
            <button onClick={handleClick}>클릭하세요</button>
        </div>
    );
};

DOM Input 값을 State에 저장하기

const App = () => {
    const [inputValue, setInputValue] = useState("defaultValue");
    const handleChange = (event) => { 
        setInputValue(event.target.value);
    }
    return (
        <div>
            <input onChange={hadleChange} defaultValue={inputValue} />
            <br />
            입력한 값은: {inputValue}
        </div>
        );
};

event object의 target은 이벤트의 원인이 되는 Element를 가리킨다.
현재 event의 target은 input element이므로 입력된 value를 가져와 setState를 하는 모습이다.

여러 Input 동시에 처리하기, 한 개의 이벤트 핸들러를 여러 Element에 재사용하기 :: object의 key를 동적으로 할당

const App = () => {
    const [user, setUser] = useState({ 
        name; "철수",
        school: "한국대학교" 
    });
 
    const handleChange = (event) => {
        const { name, value } = event.target;
 
        // 방법 1
        // const newUser = { ...user };
        // newUser[name] = value;
        // setUser(newUser);
 
        // 방법 2
        setUser((current) => {
        const newUser = {...current};
        newUser[name] = value;
        return newUser;
    })
    };
 
    return (
        <div>
        <input name="name" onChange={handleChange} value={user.name} />
        <br />
        <input name="school" onChange={handleChange} value={user.school} />
        <p>
            {user.name}님은 {user.school}에
            재학중입니다.
        </p>
    </div>
    );
};

State를 여러 개 선언할 수도 있지만 object를 활용하여 여러 개의 input을 state로 관리하는 방법이 있다.
target으로부터 name을 받아와 해당 name의 key에 해당하는 value를 변경하여 state에 반영한다.

컴포넌트 간 이벤트 전달하기

// 자식
const MyForm = ({ onChange }) => {
    return (
        <div>
            <span>이름: </span>
            <input onChange={onChange} />
        </div>
    )
}

const App = () => {
    const [username, setUsername] = useState('')
    return (
        <div>
            <h1>{username}님 환영합니다.</h1>
            <MyForm onChange={(event) => { setUsername(event.target.value) } }/>
        </div>
    )
}

사용자가 입력한 정보를 현재 컴포넌트가 아닌 부모 컴포넌트에서 활용해야 하는 경우 예시와 같이 이벤트를 Props로 전달하여 처리할 수 있다.

커스텀 이벤트

const SOS = ({onSOS}) => {
    const [count, setCount] = useState(0);
 
    const handleClick = () => {
        if(count >= 2) {
            onSOS();
        }
        setCount(count + 1);
    }
 
    return <button onClick={handleClick}>세 번 누르면 긴급호출({count})</button>
}
const App = () => {
    return (
        <div>
            <SOS onSOS={() => { alert("긴급사태!"); }} />
        </div>
    );
};

단순히 DOM 이벤트를 활용하는 것을 넘어서 나만의 이벤트를 만들 수도 있다.

참고자료

리액트 공식 사이트 - 이벤트 처리하기
React 이벤트 처리
[React] 리액트에서 이벤트를 다루는 방법

profile
문제를 해결하고 가치를 제공합니다
post-custom-banner

0개의 댓글