Skip to content
This page has been auto-translated and may contain errors.View in English

이벤트

버튼을 만들었습니다. 이제 누군가 버튼을 클릭할 때, 폼을 저장할 때, 메뉴를 열 때, 항목을 삭제할 때 실제로 무언가가 일어나야 합니다. React는 다른 모든 것을 다루는 것과 같은 방식으로 이를 처리합니다. 바로 props를 통해서입니다. JavaScript 이벤트 장에서 했던 것처럼 addEventListener를 호출하는 대신, 함수를 직접 수신하려는 요소의 prop으로 전달합니다. 기본 개념은 같습니다. 무언가 일어날 때 실행되는 함수이지만, 이를 연결하는 방식은 React 고유의 패턴입니다.

핸들러 연결하기

jsx
function SaveButton() {
  function handleClick() {
    console.log('clicked')
  }
  return <button onClick={handleClick}>Save</button>
}

이벤트 props는 camelCase로 명명되며, 수신하는 이벤트를 나타냅니다. 클릭은 onClick, 필드 값 변경은 onChange, 폼 제출은 onSubmit입니다. prop을 요소에 작성하고, 실행할 함수를 전달합니다.

handleClick은 컴포넌트 내부에 정의되고 onClick으로 전달됩니다. React는 버튼이 클릭될 때마다 이를 호출합니다. 함수를 이름으로 전달하는 것입니다, handleClick. 이를 호출한다면, handleClick()이면, 렌더링 중에 즉시 실행됩니다. 당신은 React에 나중에 실행할 함수를 전달하는 것이지, 지금 당장 이를 실행하는 것이 아닙니다.

무엇이 일어났는지에 대한 세부 사항이 필요할 때, React는 핸들러에 target, preventDefault()addEventListener에서 기대하는 것과 같은 친숙한 속성들을 가진 **이벤트 객체**를 전달합니다. 파라미터를 이름 지어 이를 받습니다. 관례적으로 event라고 합니다:

jsx
function SearchBox() {
  function handleChange(event) {
    console.log(event.target.value)
  }
  return <input onChange={handleChange} />
}

event.target은 이벤트가 발생한 요소이고, event.target.value는 필드의 현재 텍스트입니다. 핸들러가 실제로 그 정보가 필요할 때에만 이벤트 객체에 접근하면 됩니다. 버튼의 onClick은 종종 그럴 필요가 없습니다.

가장 흔한 실수

핸들러는 prop으로 전달하는 함수이기 때문에, 거의 모든 사람이 어느 시점에는 범하는 실수가 있습니다:

jsx
// 잘못됨: 컴포넌트가 렌더링될 때 handleClick을 즉시 호출합니다
<button onClick={handleClick()}>Save</button>

// 옳음: 함수 자체를 전달하고, React가 클릭할 때 이를 호출합니다
<button onClick={handleClick}>Save</button>

괄호가 전부입니다. handleClick()은 렌더링 중에 그 순간 함수를 실행하고, 그것이 반환하는 것(보통 undefined)이 onClick에 끝나게 됩니다. handleClick은 클릭이 실제로 일어날 때마다 호출할 수 있도록 React에 함수 자체를 전달합니다. 핸들러가 페이지가 로드되는 순간 자동으로 발생하는 것처럼 보인다면, 거의 항상 이 때문입니다.

핸들러를 props로 전달하기

핸들러가 이를 연결한 요소와 같은 컴포넌트에 있을 필요는 없습니다. 부모에서 정의하고 다른 모든 값처럼 자식에 prop으로 전달할 수 있습니다:

jsx
function SaveButton({ onSave }) {
  return <button onClick={onSave}>Save</button>
}

function Form() {
  function handleSave() {
    console.log('saved')
  }
  return <SaveButton onSave={handleSave} />
}

FormhandleSave를 소유하고 이를 onSave라는 prop 이름으로 SaveButton에 전달합니다. SaveButton은 함수가 무엇을 하는지 알거나 신경 쓸 필요가 없으며, 이를 onClick에 연결합니다. 이것이 작고 재사용 가능한 컴포넌트의 클릭이 앱의 더 높은 곳, 상태나 그 로직이 필요로 하는 데이터에 더 가까운 곳에 있는 로직을 트리거하는 방법입니다.

기본 동작 방지하기

어떤 이벤트는 브라우저의 기본 동작이 붙어 있으며, 폼 제출이 가장 먼저 마주하게 될 것입니다. 기본적으로 폼을 제출하면 페이지가 다시 로드되어 컴포넌트가 하던 작업이 모두 사라집니다. 핸들러 내에서 event.preventDefault()를 호출하여 이를 중지합니다:

jsx
function SignupForm() {
  function handleSubmit(event) {
    event.preventDefault()
    console.log('form submitted')
  }
  return (
    <form onSubmit={handleSubmit}>
      <input type="email" />
      <button type="submit">Sign up</button>
    </form>
  )
}

onClick을 버튼에 붙이지 말고 onSubmit<form> 자체에 붙이세요. 그렇게 하면 필드 내에서 Enter를 누르는 것도 폼을 제출하고, 버튼을 클릭하는 것만이 아닙니다.

React가 전달하는 이벤트 객체는 네이티브 브라우저 이벤트가 아닙니다. React가 만든 래퍼로, 브라우저 간의 차이를 정규화하여 같은 코드가 어느 브라우저에서 이벤트가 발생했는지 확인할 필요 없이 모든 곳에서 작동하도록 합니다. target, preventDefault(), key 등 기대할 만한 속성들을 가지고 있지만, React의 고유한 객체입니다.

또한 React는 onClick이나 onChange prop을 가진 모든 요소에 리스너를 붙이지 않습니다. 앱의 루트에 단일 리스너를 붙이고 이벤트 버블링을 사용하여 어느 컴포넌트의 핸들러가 주어진 이벤트를 위해 실행되어야 하는지 파악합니다. 이것이 앱이 처음 렌더링될 때 아직 존재하지 않는 요소의 경우에도 이벤트 처리가 작동하는 이유입니다. 나중에 목록에 추가된 항목은 여전히 onClick을 올바르게 발생시킵니다. 루트의 리스너가 처음부터 해당 특정 요소에 연결된 적이 없기 때문입니다.

Juno핸들러는 props의 함수입니다 이벤트 props는 onClick, onChange 같이 명명되며, 하나를 실행한 결과가 아니라 실행할 함수를 전달합니다. onClick={handleClick}으로 작성하고, onClick={handleClick()}은 절대 사용하지 마세요. 핸들러가 무엇이 일어났는지에 대한 세부 사항이 필요할 때, event라는 이름의 파라미터로 이들을 받습니다.
Juno핸들러는 props의 함수입니다onClick, onChange, onSubmit 같은 camelCase props로 핸들러를 붙이고, 호출이 아니라 함수 참조를 전달합니다. 부모에서 핸들러를 정의하고 로직이 더 높은 곳에 속할 때 자식으로 prop으로 전달하세요. 그리고 제출 핸들러에서 event.preventDefault()를 호출하세요. 그렇지 않으면 페이지가 상태 밖에서 다시 로드됩니다.
Juno핸들러는 props의 함수입니다 React의 이벤트 객체는 네이티브 객체 위의 합성 래퍼로, 브라우저 간에 정규화되며, React는 요소당 하나가 아니라 루트에 단일 리스너를 붙이고 이벤트를 올바른 핸들러로 라우팅하기 위해 버블링에 의존합니다. 일상적인 규칙은 그 아래에서도 유지됩니다: React에 함수를 전달하고, 직접 호출하지 마세요. 그리고 폼의 onSubmit에서 event.preventDefault()를 호출하여 브라우저의 기본 네비게이션을 인수하세요.

다음: 조건부 렌더링. 컴포넌트가 반환하는 것이 가진 데이터에 의존하기 시작합니다.