onClick={함수} , onChange={함수} , onKeyPress={함수} 등으로 표현한다.
자바스크립트에 익숙하다면 쉽게 활용할 수 있다
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:''})
}
asdf = (e) => {
if(e.key==='Enter')
this.handleClick()
}
render(){
return (
<div>
<h1>이벤트연습</h1>
<input
type="text"
name="username"
placeholder="사용자명"
value={this.state.username}
onChange={this.handleChange}
/>
<input
type="text"
name="message"
placeholder="암거나입력ㄱ"
value={this.state.message}
onChange={this.handleChange}
onKeyPress={this.asdf}
/>
<button onClick={this.handleClick}>확인</button>
</div>
)
}
}
export default EventPractice
HTML에 id가 있다면
리액트에는 ref가 있다!
state변경만으로 해결할 수 없는 상황일 때 사용!
아래처럼 DOM을 꼭 직접적으로 건드려야 할 때 사용한다!!
ref라는 콜백 함수를 props로 전달해 주면 된다.
예시 :
(...중략...)
<input ref={(ref)=>{this.input=ref}} />
(...중략...)
리액트에 내장되어 있는 함수로, v16.3부터 도입되어 이전버전 사용 불가
(콜백함수 쓰는게 더 편하다)
예시 :
import React, {Component} from 'react';
class RefSample extends Component {
input = React.createRef();
render(){
return (
<div>
<input ref={this.input}/>
</div>
(...중략...)
컴포넌트 내부에서 DOM에 직접 접근해야 할때 사용!
먼저 ref를 사용하지 않고도 원하는 기능을 구현할 수 있는지 반드시 고려한 후 활용할것!
함수형 컴포넌트는 ref 쓸려면 Hook 함수를 사용한다. 나중에 배운다
오른쪽이 map 함수를 이용해 컴포넌트를 반복했다. 왼쪽보다 짧고 좋다.
그러나 오른쪽의 경우.. 앗! 야생의 "key" prop 이 없다는 경고 메세지가 나타난다!
key는 컴포넌트 배열을 렌더링했을 때 어떤 원소에 변동이 있었는지 알아내려고 사용한다.
key 값은 언제나 유일해야 된다!
key가 없을 때 : Virtual DOM을 비교하는 과정에서 리스트를 순차적으로 비교하면서 변화 감지
key 있을 때 : (리스트에) 어떤 변화가 일어났는지 더욱 빠르게 알아냄
이렇게 쓰면 경고가 없어진다 :
import React from 'react';
const IterationSample = () => {
const name = [1,2,3,4,5]
const lists = name.map( (name,index) => <li key={index}>{name}</li>)
return <ul>
{lists}
</ul>
}
export default IterationSample;
아래 코드 안보고 만들어보자!
이거 자바스크립트로 짜려면
복잡하게 createElement, appendChild, removeChild 이런거 썼던거 같던데..
역시 리액트!... (하지만 난 아직 자바스크립트가 편한데..)
import React, {useState} from 'react';
const IterationSample = () => {
const [names, setNames] = useState([
{ id:1, text:'눈사람' },
{ id:2, text:'얼음'},
{ id:3, text:'눈'},
{ id:4, text:'바람'}
])
const [inputText,setInputText] = useState('');
const [nextId, setNextId] = useState(5);
const onChange = (e) => setInputText(e.target.value);
const Dblclick = id => {
const NewNames = names.filter( name => id !== name.id)
setNames(NewNames)
}
const namesList = names.map(name => <li key={name.id}
onDoubleClick={() => Dblclick(name.id)}>{name.text}</li>)
return (
<>
<input value={inputText} onChange={onChange}/>
<button onClick={ () => {
const nextNames = names.concat({
id: nextId,
text: inputText
})
setNames(nextNames)
setInputText('')
setNextId(nextId+1)
}
}>추가</button>
<ul>{namesList}</ul>
</>
)
}
export default IterationSample;
배열을 변형할 때는 배열에 직접 접근하여 수정하는 것이 아니라 concat, filter 등 배열 내장 함수를 사용해 새 배열을 만든 후, 이를 새로운 상태로 설정해 주어야 한다는 걸 명심하자!
객체 안에서 key를 []로 감싸면 그 안에 넣은 레퍼런스가 가리키는 실제 값이 key값으로 사용됩니다.
이벤트 예제에서 조금 막혔던 부분이 있었다. 기억할것!
예시 :
const name = 'variantKey'
const object = { [name]:'value' }
책 - 리액트를 다루는 기술(개정판) | 김민준 | 길벗