[๋ฆฌ์กํธ๋ฅผ ๋ค๋ฃจ๋ ๊ธฐ์ ] 4์ฅ - ์ด๋ฒคํธ ํธ๋ค๋ง
์ด ๊ธ์ ๊น๋ฏผ์ค(velopert)๋์ ๋ฆฌ์กํธ๋ฅผ ๋ค๋ฃจ๋ ๊ธฐ์ ์์ฐธ์กฐํ์ฌ ์์ฑํ ๊ธ์ ๋๋ค.
#
๋ฆฌ์กํธ์ ์ด๋ฒคํธ ์์คํ ์ฌ์ฉ์๊ฐ ์น ๋ธ๋ผ์ฐ์ ์์ DOM ์์๋ค๊ณผ ์ํธ ์์ฉํ๋ ๊ฒ์ ์ด๋ฒคํธ(event)๋ผ๊ณ ํ๋ค. ๋ฆฌ์กํธ์ ์ด๋ฒคํธ ์์คํ ์ ์น ๋ธ๋ผ์ฐ์ ์ HTML ์ด๋ฒคํธ์ ์ธํฐํ์ด์ค๊ฐ ๋์ผํ๊ธฐ ๋๋ฌธ์ ์ฌ์ฉ๋ฒ์ด ๊ฝค ๋น์ทํ๋ค. ํ์ง๋ง ์ฃผ์ํด์ผ ํ ๋ช ๊ฐ์ง ์ฌํญ์ด ์๋ค.
#
์ด๋ฒคํธ ์ฌ์ฉ ์ ์ฃผ์ ์ฌํญ์ด๋ฒคํธ ์ด๋ฆ์ ์นด๋ฉ ํ๊ธฐ๋ฒ์ผ๋ก
HTML์์๋
onclick
์ผ๋ก ์์ฑํ์ง๋ง ๋ฆฌ์กํธ์์๋ ์นด๋ฉ ํ๊ธฐ๋ฒ์ผ๋กonClick
์ผ๋ก ์์ฑํด์ผ ํ๋ค.์ด๋ฒคํธ์๋ ํจ์ ํํ์ ๊ฐ์ ์ ๋ฌ.
HTML์์ ์ด๋ฒคํธ๋ฅผ ์ค์ ํ ๋ ํฐ๋ฐ์ดํ ์์ ์คํํ ์ฝ๋๋ฅผ ๋ฃ์์ง๋ง, ๋ฆฌ์กํธ์์๋ ํจ์ ํํ์ ๊ฐ์ฒด๋ฅผ ์ ๋ฌํ๋ค. ํ์ดํ ํจ์ ๋ฌธ๋ฒ์ ์ฌ์ฉํ๊ฑฐ๋ ํน์ ์ธ๋ถ์ ๋ฏธ๋ฆฌ ํจ์๋ฅผ ๋ง๋ค์ด์ ์ ๋ฌํ๊ธฐ๋ ํ๋ค.
DOM ์์์๋ง ์ด๋ฒคํธ๋ฅผ ์ค์ ํ ์ ์๋ค.
div, button, input, form, span ๋ฑ์ DOM ์์์๋ ์ด๋ฒคํธ๋ฅผ ์ค์ ํ ์ ์์ง๋ง, ์ง์ ๋ง๋ ๋ฆฌ์กํธ ์ปดํฌ๋ํธ์๋ ์ด๋ฒคํธ๋ฅผ ์์ฒด์ ์ผ๋ก ์ค์ ํ ์ ์๋ค.
<MyComponent onClick={doSomething} />
์ด ์ฝ๋๋ ์ด๋ฆ์ด
onClick
์ธprops
๋ฅผ ์ปดํฌ๋ํธ์ ์ ๋ฌํ ๋ฟ์ด๋ค.์ปดํฌ๋ํธ์ ์์ฒด์ ์ผ๋ก ์ด๋ฒคํธ๋ฅผ ์ค์ ํ ์๋ ์์ง๋ง, ์ ๋ฌ๋ฐ์ props ๋ฅผ ์ปดํฌ๋ํธ๋ด๋ถ์ DOM ์ด๋ฒคํธ๋ก ์ค์ ํ ์๋ ์๋ค.
<div onClick={this.props.onClick}>{/* ... */}</div>
๋ฆฌ์กํธ์์ ์ง์ํ๋ ๋ค์ํ ์ด๋ฒคํธ ์ข ๋ฅ๋ ์๋์ ๋งํฌ๋ฅผ ํตํด ํ์ธํ ์ ์๋ค.
ํฉ์ฑ ์ด๋ฒคํธ(SyntheticEvent) - React
#
์ด๋ฒคํธ ํธ๋ค๋ง ์์ #
์ปดํฌ๋ํธ ์์ฑ ๋ฐ ๋ถ๋ฌ์ค๊ธฐsrc ๋๋ ํ ๋ฆฌ์ EventPractice.js
ํ์ผ์ ๋ง๋ค๊ณ App ์ปดํฌ๋ํธ์์ ๋ถ๋ฌ์ ๋ ๋๋งํ๋ค.
EventPractice.js
import React, {Component} from 'react';
class EventPractice extends Component { render() { return ( <div> <h1>Event Practice</h1> </div> ); }}
export default EventPractice;
App.js
import React from 'react';import EventPractice from './Practice';
const App = () => { return <EventPractice />;};
export default App;
onChange
์ด๋ฒคํธ ํธ๋ค๋งํ๊ธฐ#
EventPractice
์ปดํฌ๋ํธ์ input ์์๋ฅผ ๋ ๋๋งํ๋ ์ฝ๋์ ํด๋น ์์์ onChange ์ด๋ฒคํธ๋ฅผ ์ค์ ํ๋ ์ฝ๋๋ฅผ ์์ฑํ๋ค.
import React, {Component} from 'react';
class EventPractice extends Component { render() { return ( <div> <h1>Event Practice</h1> <input type="text" name="message" placeholder="type something" onChange={(e) => { console.log(e); }} /> </div> ); }}
export default EventPractice;
yarn start
๋๋ npm start
๋ก ๋ฆฌ์กํธ ์ฑ์ ์คํํ๊ณ , F12
๋ฅผ ๋๋ฌ ์ฝ์ ์ฐฝ์ํจํ input ์์์ ์๋ฌด ํ
์คํธ๋ฅผ ์
๋ ฅํด๋ณธ๋ค.
์ฝ์์ SyntheticzEvent
๋ผ๋ ๊ฐ์ฒด๊ฐ ๋ํ๋๋ ๊ฒ์ ๋ณผ ์ ์๋๋ฐ, ์ด ๊ฐ์ฒด๋ ์น ๋ธ๋ผ์ฐ์ ์ ๋ค์ดํฐ๋ธ ์ด๋ฒคํธ๋ฅผ ๊ฐ์ธ๋ ๊ฐ์ฒด๋ก, ์ด๋ฒคํธ ํจ์์ ํ๋ผ๋ฏธํฐ(์์ ์ฝ๋์์๋ e
)๋ก ์ ๊ทผํ ์ ์๋ค.
๋ค์ดํฐ๋ธ ์ด๋ฒคํธ์ ์ธํฐํ์ด์ค๊ฐ ๊ฐ์ผ๋ฏ๋ก, ์์ JS์์ HTML ์ด๋ฒคํธ๋ฅผ ๋ค๋ฃฐ ๋์ ๋๊ฐ์ด ์ฌ์ฉํ๋ฉด ๋์ง๋ง, ๋ค์ดํฐ๋ธ ์ด๋ฒคํธ์ ๋ฌ๋ฆฌ ์ด๋ฒคํธ๊ฐ ๋๋๋ฉด ์ด๋ฒคํธ๊ฐ ์ด๊ธฐํ ๋๋ฏ๋ก ์ ๋ณด๋ฅผ ์ฐธ์กฐํ ์ ์๊ธฐ ๋๋ฌธ์, ๋น๋๊ธฐ์ ์ผ๋ก ์ด๋ฒคํธ ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํด์ผ ํ๋ค๋ฉด e.persist()
ํจ์๋ฅผ ํธ์ถํด ์ฃผ์ด์ผ ํ๋ค.
์ด์ state
์ input ๊ฐ์ ๋ด์๋ณด๋๋ก ํ๋ค. state
์ด๊ธฐ๊ฐ์ ์ค์ ํ๊ณ ์ด๋ฒคํธ ํธ๋ค๋ง ํจ์ ๋ด๋ถ์์ this.setState
๋ฉ์๋๋ฅผ ํธ์ถํ์ฌ state
๋ฅผ ์
๋ฐ์ดํธํ๋ค.
import React, {Component} from 'react';
class EventPractice extends Component { state = { message: '', };
render() { return ( <div> <h1>Event Practice</h1> <input type="text" name="message" placeholder="type something" value={this.state.message} onChange={(e) => { this.setState({ message: e.target.value, }); }} /> </div> ); }}
export default EventPractice;
์ธํ์ ์๋ฌด๊ฑฐ๋ ์
๋ ฅํ์ ๋ ์ค๋ฅ๊ฐ ๋ฐ์ํ์ง ์๋๋ค๋ฉด state
์ ํ
์คํธ๋ฅผ ์ ๋ด์๊ฒ์ด๋ค.
์ด์ input ์์ ์๋์ button ์ ํ๋ ๋ง๋ค๊ณ , ํด๋ฆญ ์ด๋ฒคํธ๊ฐ ๋ฐ์ํ๋ฉด ํ์ฌ input ์ ๋ด๊ธด ํ ์คํธ๋ฅผ ๋์ด ํ ๊ณต๋ฐฑ์ผ๋ก ์ค์ ํ๋๋ก ํ๋ค.
import React, {Component} from 'react';
class EventPractice extends Component { state = { message: '', };
render() { return ( <div> <h1>Event Practice</h1> <input type="text" name="message" placeholder="type something" value={this.state.message} onChange={(e) => { this.setState({ message: e.target.value, }); }} /> <button onClick={() => { alert(this.state.message); this.setState({ message: '', }); }} > Submit </button> </div> ); }}
export default EventPractice;
#
์์ ๋ฉ์๋ ๋ง๋ค๊ธฐํ์ฌ์ ์ฝ๋๋ ์ด๋ฒคํธ์ ์คํํ ํจ์๋ฅผ ๋ ๋๋ง ๋ฉ์๋ ๋ด๋ถ์ ๋ง๋ค์ด์ ์ ๋ฌํด์ฃผ๊ณ ์๋ค. ์ด ๋ฐฉ๋ฒ ๋์ ํจ์๋ฅผ ๋ฏธ๋ฆฌ ๋ง๋ค์ด ์ ๋ฌํ๋ฉด ๊ฐ๋ ์ฑ์ ๋์ผ ์ ์๋ค.
import React, {Component} from 'react';
class EventPractice extends Component { state = { message: '', };
constructor(props) { super(props); this.handleChange = this.handleChange.bind(this); this.handleClick = this.handleClick.bind(this); }
handleChange(e) { this.setState({ message: e.target.value, }); }
handleClick() { alert(this.state.message); this.setState({ message: '', }); }
render() { return ( <div> <h1>Event Practice</h1> <input type="text" name="message" placeholder="type something" value={this.state.message} onChange={this.handleChange} /> <button onClick={this.handleClick}>Submit</button> </div> ); }}
export default EventPractice;
์ฌ๊ธฐ์ ์ฃผ์ํด์ผํ ์ ์ this ๋ฐ์ธ๋ฉ์ด๋ค. this๋ ํจ์๊ฐ ์ด๋์ ํธ์ถ๋๋์ง์ ๋ฐ๋ผ๊ฒฐ์ ๋๋ค. ํด๋์ค์ ์์ ๋ฉ์๋๊ฐ ํน์ HTML ์์์ ์ด๋ฒคํธ๋ก ๋ฑ๋ก๋๋ ๊ณผ์ ์์ ๋ฉ์๋์ this์ ๊ด๊ณ๊ฐ ๋์ด์ง๊ฒ ๋๋ค.
๋ฐ๋ผ์ this๋ฅผ ์ปดํฌ๋ํธ ์์ ์ผ๋ก ๊ฐ๋ฅดํค๊ฒ ํ๊ธฐ ์ํด ๋ฉ์๋๋ฅผ this์ ๋ฐ์ธ๋ฉํ๋ ์์
์ด ํ์ํ๊ณ , ํ์ฌ ์ฝ๋์์๋ constructor
ํจ์ ๋ด๋ถ์์ ํจ์๋ฅผ ๋ฐ์ธ๋ฉํ๊ณ ์๋ค. ๋ฉ์๋ ๋ฐ์ธ๋ฉ์ ์ด๋ ๊ฒ ์์ฑ์ ๋ฉ์๋์์ ํ๋ ๊ฒ์ด ์ ์์ด๋ค. ์ ๋ฉ์๋๋ฅผ ๋ง๋ค ๋๋ง๋ค constructor
๋ ์์ ํด์ผํ๊ธฐ ๋๋ฌธ์ด๋ค.
ํ์ง๋ง ํด๋์คํ ์ปดํฌ๋ํธ์์ public class fields ๋ฌธ๋ฒ์ ์ฌ์ฉํ์ฌ ํ์ดํ ํจ์๋ก ๋ฉ์๋๋ฅผ ๊ตฌํํ๋ฉด, ์ข ๋ ํธํ๊ฒ ์์ฑํ ์ ์๋ค. ํ์ดํ ํจ์์ this๋ ๋ถ๋ชจ ํจ์์ this๋ฅผ ์์๋ฐ๋๋ฐ JS์์ ํด๋์ค๋ ํจ์๋ก ๊ตฌํ๋์ด์๊ธฐ ๋๋ฌธ์ this๋ ์ปดํฌ๋ํธ ์์ ์ด ๋๋ฏ๋ก bind(this)๋ฅผ ํ์ง ์์๋ ๋๋ค.
import React, {Component} from 'react';
class EventPractice extends Component { state = { message: '', };
handleChange = (e) => { this.setState({ message: e.target.value, }); };
handleClick = () => { alert(this.state.message); this.setState({ message: '', }); };
render() { return ( <div> <h1>Event Practice</h1> <input type="text" name="message" placeholder="type something" value={this.state.message} onChange={this.handleChange} /> <button onClick={this.handleClick}>Submit</button> </div> ); }}
export default EventPractice;
์ด ๋ฌธ๋ฒ์ ์คํ์ ์ธ ๋ฌธ๋ฒ์ผ๋ก ๋ฐ๋ฒจ์ ์ค์ ํด์ฃผ์ด์ผ ํ๋๋ฐ Create-React-App ์ผ๋ก ๋ง๋ ํ๋ก์ ํธ๋ ์ด ๋ฌธ๋ฒ์ด ๊ธฐ๋ณธ์ ์ผ๋ก ์ค์ ๋์ด ์์ผ๋ฏ๋ก ์ฌ์ฉ ๊ฐ๋ฅํ๋ค.
#
input ์ฌ๋ฌ ๊ฐ ๋ค๋ฃจ๊ธฐ์ด์ input ๊ฐ์ state
์ ๋ฃ๋ ๋ฐฉ๋ฒ์ ๋ฐฐ์ ๋ค. ๊ทธ๋ฐ๋ฐ input ์ด ์ฌ๋ฌ ๊ฐ์ผ ๋๋ ์ด๋ป๊ฒ ํด์ผํ ๊น? ๋ฉ์๋๋ฅผ ์ฌ๋ฌ ๊ฐ ๋ง๋ค์ด ํด๊ฒฐํ ์ ์์ง๋ง, event
๊ฐ์ฒด๋ฅผ ํ์ฉํ๋ฉด๋ ์ฝ๊ฒ ์ฒ๋ฆฌํ ์ ์๋ค.
onChange
์ด๋ฒคํธ ํธ๋ค๋ฌ์์ e.target.name
์ ํด๋น input์ name์ ๊ฐ๋ฆฌํจ๋ค. ์ด๊ฐ์ ์ด์ฉํด state๋ฅผ ์ค์ ํ๋ฉด ์ฝ๊ฒ ํด๊ฒฐํ ์ ์๋ค.
import React, {Component} from 'react';
class EventPractice extends Component { state = { username: '', message: '', };
handleChange = (e) => { this.setState({ [e.target.name]: e.target.value, }); };
handleClick = () => { alert(this.state.username + ': ' + this.state.message); this.setState({ username: '', message: '', }); };
render() { return ( <div> <h1>Event Practice</h1> <input type="text" name="username" placeholder="User name" value={this.state.username} onChange={this.handleChange} /> <input type="text" name="message" placeholder="type something" value={this.state.message} onChange={this.handleChange} /> <button onClick={this.handleClick}>Submit</button> </div> ); }}
export default EventPractice;
handleChange = (e) => { this.setState({ [e.target.name]: e.target.value, });};
์ด ์ฝ๋๋ฅผ ๋ณด๋ฉด e.target.name
์ []
๋ก ๊ฐ์ธ๋๋ฐ, ์ด๋ ๊ฒ ๊ฐ์ฒด ์์์ key๋ฅผ []
๋ก ๊ฐ์ธ๋ฉด ๊ทธ ์์ ๋ฃ์ ๋ ํผ๋ฐ์ค๊ฐ ๊ฐ๋ฆฌํค๋ ์ค์ ๊ฐ์ด key ๊ฐ์ผ๋ก ์ฌ์ฉ๋๋ค.
onKeyPress
์ด๋ฒคํธ ํธ๋ค๋ง#
ํค๋ฅผ ๋๋ ์ ๋ ๋ฐ์ํ๋ KeyPress
์ด๋ฒคํธ๋ฅผ ์ฒ๋ฆฌํด๋ณธ๋ค. ๋ ๋ฒ์งธ ์ธํ์์ Enter
ํค๋ฅผ ๋๋ ์ ๋ handleCick
๋ฉ์๋๋ฅผ ํธ์ถํ๋๋ก ์ฝ๋๋ฅผ ์ถ๊ฐํ๋ค.
import React, {Component} from 'react';
class EventPractice extends Component { state = { username: '', message: '', };
handleChange = (e) => { this.setState({ [e.target.name]: e.target.value, }); };
handleClick = () => { alert(this.state.username + ': ' + this.state.message); this.setState({ username: '', message: '', }); };
handleKeyPress = (e) => { if (e.key === 'Enter') { this.handleClick(); } };
render() { return ( <div> <h1>Event Practice</h1> <input type="text" name="username" placeholder="User name" value={this.state.username} onChange={this.handleChange} /> <input type="text" name="message" placeholder="type something" value={this.state.message} onChange={this.handleChange} onKeyPress={this.handleKeyPress} /> <button onClick={this.handleClick}>Submit</button> </div> ); }}
export default EventPractice;
#
ํจ์ํ ์ปดํฌ๋ํธ๋ก ๊ตฌํํด ๋ณด๊ธฐ์ด์ ํด๋์คํ ์ปดํฌ๋ํธ๋ก ์์ฑํ๋ EventPractice ์ปดํฌ๋ํธ๋ฅผ ํจ์ํ ์ปดํฌ๋ํธ๋ก ๋ฐ๊พธ์ด๋ณธ๋ค.
EventPractice.js
import React, {useState} from 'react';
const EventPractice = () => { const [username, setUsername] = useState(''); const [message, setMessage] = useState(''); const onChangeUsername = (e) => setUsername(e.target.value); const onChangeMessage = (e) => setMessage(e.target.value); const onClick = () => { alert(username + ': ' + message); setUsername(''); setMessage(''); }; const onKeyPress = (e) => { if (e.key === 'Enter') { onClick(); } };
return ( <div> <h1>Event Practice</h1> <input type="text" name="username" placeholder="User name" value={username} onChange={onChangeUsername} /> <input type="text" name="message" placeholder="type something" value={message} onChange={onChangeMessage} onKeyPress={onKeyPress} /> <button onClick={onClick}>Submit</button> </div> );};
export default EventPractice;
๊ธฐ๋ฅ์ด ์ด์ ๊ณผ ๊ฐ์ด ๋์ํ๋์ง ํ์ธํด๋ณธ๋ค.
์์ ํจ์ํ ์ปดํฌ๋ํธ ์ฝ๋์์๋ e.target.name
์ ์ฌ์ฉํ์ง ์๊ณ onChange
๊ด๋ จํจ์๋ฅผ ๋ฐ๋ก ๋ง๋ค์๋ค. ํ์ง๋ง input์ ๊ฐ์๊ฐ ๋ง์์ง์๋ก ๋ถํธํด์ง๋ฏ๋ก, e.target.name
์ ํ์ฉํ๋ ๊ฒ์ด ๋ ์ข์ ์ ์๋ค.
import React, {useState} from 'react';
const EventPractice = () => { const [form, setForm] = useState({ username: '', message: '', }); const {username, message} = form; const onChange = (e) => { const nextForm = { ...form, [e.target.name]: e.target.value, }; setForm(nextForm); }; const onClick = () => { alert(username + ': ' + message); setForm({ username: '', message: '', }); }; const onKeyPress = (e) => { if (e.key === 'Enter') { onClick(); } };
return ( <div> <h1>Event Practice</h1> <input type="text" name="username" placeholder="User name" value={username} onChange={onChange} /> <input type="text" name="message" placeholder="type something" value={message} onChange={onChange} onKeyPress={onKeyPress} /> <button onClick={onClick}>Submit</button> </div> );};
export default EventPractice;
e.target.name
๊ฐ์ ํ์ฉํ๋ ค๋ฉด useState
๋ฅผ ์ฌ์ฉํ ๋ input ๊ฐ๋ค์ด ๋ค์ด์๋ ๊ฐ์ฒด๋ฅผ ์ ์ํด ์ฌ์ฉํ๋ฉด ๋๋ค.
#
์ ๋ฆฌ๋ฆฌ์กํธ์์ ์ด๋ฒคํธ๋ฅผ ๋ค๋ฃจ๋ ๊ฒ์ ์์ JS ๋๋ jQuery๋ฅผ ์ฌ์ฉํ ์น ์ ํ๋ฆฌ์ผ์ด์ ์์์ด๋ฒคํธ๋ฅผ ๋ค๋ฃจ๋ ๊ฒ๊ณผ ๋น์ทํ๋ค. ๋ฐ๋ผ์ ๊ธฐ์กด HTML DOM Event๋ฅผ ์๊ณ ์๋ค๋ฉด ๋ฆฌ์กํธ์์ปดํฌ๋ํธ ์ด๋ฒคํธ๋ ์ฝ๊ฒ ๋ค๋ฃฐ ์ ์๋ค.
#
๊ฐ์ด ์ฝ๊ธฐ์ด๋ฒคํธ ์ฒ๋ฆฌํ๊ธฐ - React