HTML의 DOM 요소에서 이벤트를 처리하는 방식과 매우 유사함
React에서 이벤트 이름은 소문자 대신 camelCase를 사용함
React에서는 이벤트에 실행할 자바스크립트 코드를 전달하는 것이 아니라, 함수 형태의 값을 전달함
React에서는 DOM 요소에만 이벤트를 설정 가능함
// Error
<MyComponent onClick={doSomething} />
// Good
function MyComponent(props){
return (<div onClick={props.onClick}>
{/* (...) */}
</div>)
}
preventDefault
를 명시적으로 호출해야 함// JavaScript
<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>
);
}
React에서는 요소가 처음 렌더링될 때 리스너를 제공하면 됨
클래스형 컴포넌트에서 이벤트 핸들러를 등록할 때는 this
바인딩을 해주어야 함
this
가 undefined
를 가리키게 됨// 해결 방법 1
class Toggle extends React.Component {
constructor(props) {
super(props);
this.state = {isToggleOn: true};
// 콜백에서 `this`가 작동하려면 아래와 같이 바인딩 해주어야 합니다.
this.handleClick = this.handleClick.bind(this);
}
handleClick() {
this.setState(prevState => ({
isToggleOn: !prevState.isToggleOn
}));
}
render() {
return (
<button onClick={this.handleClick}>
{this.state.isToggleOn ? 'ON' : 'OFF'}
</button>
);
}
}
ReactDOM.render(
<Toggle />,
document.getElementById('root')
);
// 해결 방법 2
class LoggingButton extends React.Component {
// 이 문법은 `this`가 handleClick 내에서 바인딩되도록 합니다.
handleClick = () => {
console.log('this is:', this);
}
render() {
return (
<button onClick={this.handleClick}>
Click me
</button>
);
}
}
// 해결 방법 3
class LoggingButton extends React.Component {
handleClick() {
console.log('this is:', this);
}
render() {
// 이 문법은 `this`가 handleClick 내에서 바인딩되도록 합니다.
return (
<button onClick={() => this.handleClick()}>
Click me
</button>
);
}
}
<button onClick={(e) => this.deleteRow(id, e)}>Delete Row</button>
<button onClick={this.deleteRow.bind(this, id)}>Delete Row</button>
e
인자가 id 뒤에 두 번째 인자로 전달됨function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
<li>{number}</li>
);
return (
<ul>{listItems}</li>
);
}
const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
<NumberList numbers={numbers} />,
document.getElementById('root');
);
key
를 넣어야 한다는 경고창이 뜸React에서 key는 컴포넌트 리스트를 렌더링 했을 때 어떤 항목을 변경, 추가 또는 삭제할지 식별하는 것을 도움
key는 요소에 안정적인 고유성을 부여하기 위해 리스트 내부의 요소에 지정해야 함
const todoItems = todos.map((todo) =>
<li key={todo.id}>
{todo.text}
</li>
);
const todoItems = todos.map((todo, index) =>
// Only do this if items have no stable IDs
<li key={index}>
{todo.text}
</li>
);
<li>
요소가 아니라 <ListItem />
요소가 key를 가져야 함// bad
function ListItem(props) {
const value = props.value;
return (
<li key={value.toString()}>
{value}
</li>
);
}
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
<ListItem value={number} />
);
return (
<ul>
{listItems}
</ul>
);
}
const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
<NumberList numbers={numbers} />,
document.getElementById('root')
);
// good
function ListItem(props) {
return <li>{props.value}</li>;
}
function NumberList(props) {
const numbers = props.numbers;
const listItems = numbers.map((number) =>
<ListItem key={number.toString()} value={number} />
);
return (
<ul>
{listItems}
</ul>
);
}
const numbers = [1, 2, 3, 4, 5];
ReactDOM.render(
<NumberList numbers={numbers} />,
document.getElementById('root')
);
map()
함수 내부에 있는 요소에 key를 넣어주는 것이 좋음function Blog(props) {
const sidebar = (
<ul>
{props.posts.map((post) =>
<li key={post.id}>
{post.title}
</li>
)}
</ul>
);
const content = props.posts.map((post) =>
<div key={post.id}>
<h3>{post.title}</h3>
<p>{post.content}</p>
</div>
);
return (
<div>
{sidebar}
<hr />
{content}
</div>
);
}
const posts = [
{id: 1, title: 'Hello World', content: 'Welcome to learning React!'},
{id: 2, title: 'Installation', content: 'You can install React from npm.'}
];
ReactDOM.render(
<Blog posts={posts} />,
document.getElementById('root')
);
const content = posts.map((post) =>
<Post
key={post.id}
id={post.id}
title={post.title} />
);
function NumberList(props) {
const numbers = props.numbers;
return (
<ul>
{numbers.map((number) =>
<ListItem key={number.toString()}
value={number} />
)}
</ul>
);
}