리액트의 이벤트 시스템
웹 브라우저 HTML 이벤트와 인터페이스가 동일하기 때문에 사용 방법이 유사하다.
유의사항
이벤트 속성의 이름은 카멜 표기법으로 작성
(onclick -> onClick)
이벤트에 실행할 자바스크립트의 코드를 전달하는 것이 아닌 함수 형태의 값을 전달한다.
예)
HTML => <button onclick="alert('hello world')">클릭</button>
React => <button onClick={ () => alert('hello world') }>클릭</button>
이벤트 작성
constructor(props):
명시적으로 적지 않아도 클래스 타입의 컴포넌트를 만들 때 constructor가 자동 생성되어 props가 전달되고, 그게 다시 상위 컴포넌트 쪽으로 전달, 초기화된다.
this.props 기능들을 쓸 수 있게되는 것.
class EventButton extends React.Component {
// 명시적으로 적지 않아도 생성된다.
constructor(props) {
super(props);
}
/* 1. 직접 이벤트 속성에 함수를 정의하며 이벤트를 연결한다. */
render() {
return (
<button
onClick={ () => alert('인라인 함수 이벤트 동작 확인!') }
>
{ this.props.children }
</button>
);
}
ReactDOM.createRoot(document.getElementById('root')).render(
<EventButton>이벤트버튼</EventButton>
);
class EventButton extends React.Component {
constructor(props) {
super(props);
}
/* 2. render 함수 외부에 이벤트 함수 정의 후 함수를 전달하여 이벤트를 연결한다. */
onClickHandler = () => {
alert('외부 함수 이벤트 동작 확인!');
}
render() {
return (
<button onClick={ this.onClickHandler }>{ this.props.children }</button>
);
}
}
ReactDOM.createRoot(document.getElementById('root')).render(
<EventButton>이벤트버튼</EventButton>
);
class EventButton extends React.Component {
constructor(props) {
super(props);
}
render() {
console.log(this.props);
const { onClick, children } = this.props;
return <button onClick={ onClick }>{ children }</button>;
}
}
ReactDOM.createRoot(document.getElementById('root')).render(
<EventButton
onClick={ () => alert('props로 이벤트 전달 후 연결 확인!') }
>
이벤트버튼
</EventButton>
);
state 값을 변경 시켜주는 이벤트 핸들링
<script type="text/babel">
class EventComponent extends React.Component {
state = {
message : ''
};
render() { 이벤트 핸들링 작성};
ReactDOM.createRoot(document.getElementById('root')).render(<EventComponent/>);
</script>
render 안에 들어갈 이벤트 핸들링 작성
render() {
return (
<>
<h1>이벤트 핸들링</h1>
<input
type="text"
name="message"
placeholder="텍스트를 입력해주세요"
onChange={
(e) => {
/* 이벤트 핸들러 함수(e)의 첫번째 인자는 이벤트 객체
e.target : 이벤트 발생 대상 객체
e.target.value : input에 입력 된 값 */
console.log(e.target);
console.log(e.target.value);
this.setState({
message : e.target.value
})
}
}
/* 메세지 상태 값이 지워지는 것이 적용되도록 추가 input의 value 값까지 변경 */
value={ this.state.message }
/>
<button
onClick={
() => {
alert(this.state.message);
/* 메세지 상태 값이 지워지도록 추가 State 값만 변경되는 상태 */
this.setState({
message : ''
});
}
}
>
확인
</button>
</>
);
}
여러개의 input 태그 이벤트 다루기
이벤트 핸들러 작성
state = {
username : '',
password : ''
};
onChangeHandler = (e) => {
/* 이벤트가 발생한 태그의 name 속성 값을 key 값으로 하여 변경할 state 객체를 생성한다.
동일한 key값을 가진 state객체만 업데이트된다.
키 값은 대괄호 표기법으로 적어준다. */
this.setState({ [e.target.name] : e.target.value });
};
onClickHandler = (e) => {
alert(`username : ${this.state.username}\npassword : ${this.state.password}`);
this.setState({ username: '', password: ''});
};
키 값에는 문자열로 작성해야하기 때문에 문법적인 오류가 발생하게된다.
대괄호 표기법으로 작성해준다.
this.setState({ [e.target.name] : e.target.value });
03에서 만든 로그인 컴포넌트 -> 함수형 컴포넌트로 변경
state를 다루는 방법이 달라진다.
state를 직접 사용할 수 없기때문에 useState를 사용한다.
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
onChange 설정
user의 name의 변경이 필요하다면 setUsername을 호출
이벤트가 발생한 대상 객체의 값(e.target.value)을 설정한다.
const onChangeUsername = e => setUsername(e.target.value);
const onChangePassword = e => setPassword(e.target.value);
return (
<div>
<h1>로그인</h1>
<label>아이디</label>
<input
type="text"
name="username"
placeholder="아이디를 입력하세요"
value={ username }
onChange={ onChangeUsername }
/>
<br/>
<label>비밀번호 : </label>
<input
type="password"
name="password"
placeholder="비밀번호를 입력하세요"
value={ password }
onChange={ onChangePassword }
/>
<br/>
<button
onClick={onClickHandler}
>
로그인
</button>
</div>
04에서 만든 로그인 컴포넌트 -> 다중 태그 이벤트 핸들링으로 변경
useState를 문자열useState('');
이 아닌 객체 형태useState({});
로 변경해야한다.
// 04에서 만든 useState
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
// 05에서 만든 useState
const [form, setForm] = useState({
username : '',
password : ''
});
changedForm에 스프레드 연산자(...form)를 통해
username과 password 두 개의 값을 보존하도록 만든다.
changedForm 없이 이전에 calss 컴포넌트에서 사용한 아래 코드형식으로 적용할 경우
e.target.value 값으로 useState를 덮어쓰기 때문에
username과 password 둘 중 하나를 입력되지 않을 경우
미리 선언해두었던 useState의 키값이 삭제된다.
this.setState({ [e.target.name] : e.target.value });
const onChangeHandler = e => {
/* username 또는 password의 값이 변경될 때 동작하므로 form 객체에 전달할 객체에는 2개의 값이 모두 존재해야한다. */
const changedForm = {
...form, //스프레드 연산자를 이용하여 기존 form 객체 복사
[e.target.name] : e.target.value // 이벤트가 발생한 값만 덮어쓰기
};
setForm(changedForm);
};