리액트 프로젝트 내부에서 DOM에 이름을 다는 것
HTML의 DOM요소에 id를 다는 것과 같음
Q : 리액트 컴포넌트에서는 id 사용하면 안 되나요?
A : 있다 but 권장하지 않음. 같은 컴포넌트를 여러 번 사용한다고 가정하면 HTML에서 DOM id는 유일해야 하지만, 중복 id를 가진 DOM이 여러 개 생길 수 있음.
ref는 전역적으로 작동하지 않고 컴포넌트 내부에서만 작동하기 때문에 위와같은 문제 없음!
state만으로 해결할 수 없는, DOM을 꼭 사용해야 하는 상황
<state 복습>
import React, { Component } from 'react';
class validationSample extends Component {
state = {
password: '',
clicked: false,
validated: false
}
handleChange = (e) => {
this.setState({
password: e.target.value
});
}
handleButtonClick = () => {
this.setState({
clicked: true,
validated: this.state.password === '0000'
})
}
render() {
return (
<div>
<input
type='password'
value={this.state.password}
onChange={this.handleChange}
className={this.state.clicked? (this.state.validated ? 'success' : 'failure'): ''}
/>
<button onClick={this.handleButtonClick}>검증하기</button>
</div>
);
}
}
export default validationSample;
클래스형 컴포넌트에서 ref를 사용하는 법
(함수형은 Hooks 이후에 ㄱ)
ref 사용하는 방법
1. 콜백함수 사용하기
ref를 달고자 하는 요소에 ref라는 콜백 함수를 props로 전달한다. - this.아무이름 = ref
<input ref={(ref) => this.input = ref}/>
2. createRef 사용하기 리액트 v16.3~
컴포넌트 내부에서 멤버변수에 React.createRef() 담아준다.
해당 멤버 변수를 ref를 달고자 하는 요소에 ref props로 넣어준다.
나중에 ref를 설정해준 DOM에 접근하려면 this.input.current
로 조회한다.
import React, { Component } from 'react';
class RefSample extends Component {
input = React.createRef();
handleFocus = () => {
this.input.current.focus();
}
render() {
return (
<div>
<input ref={this.input}/>
</div>
);
}
}
export default RefSample;
3. 컴포넌트에 ref달기
컴포넌트 내부에 있는 DOM을 컴포넌트 외부에서 사용할 때 사용
< MyComponent ref={(ref) => {this.myComponent = ref}} />
or 최상위 DOM에 ref 달아주면 된다.
데이터 추가 기능 구현하기
import React from 'react';
const IterationSample = () => {
const [names, setNames] = useState([
{id:1, text:'111'},
{id:2, text:'222'},
{id:3, text:'333'},
{id:1, text:'444'}
]);
const [inputText, setInputText] = useState('');
const [nextId, setNextId] = useState(5); // 새로운 항목 추가시 사용할 id
const onChange = (e) => setInputText(e.target.value);
const onClick = () => {
const nextNames = names.concat({ //배열에 항목 추가하는 내장함수
id: nextId,
text: inputText
});
setNextId(nextId+1);
setNames(nextNames);
setInputText(''); //inputText 비우기
}
const nameList = names.map(name => <li key={name.id}>{name.text}</li>);
return (
<div>
<input value = {inputText} onChange={onChange} />
<button onClick={onClick}>추가</button>
<ul>{nameList}</ul>
</div>
);
};
export default IterationSample;
shouldComponentUpdate
의 경우 컴포넌트 업데이트 성능 개선 시 유용 (추후 다시 다룸)마운트
DOM이 생성되고 웹 브라우저 상에 나타나는 것
- constructor : 컴포넌트 생성시마다 호출되는 클래스 생성자 메서드
- getDerivedStateFromProps : props에 있는 값을 state에 저장
- render: UI 렌더링
- componentDidMount: 컴포넌트가 웹브라우저에 나타난 후 호출
업데이트
컴포넌트가 업데이트 되는 경우
- getDefivedStateFromProps : 마운트 과정, 업데이트 시작 전에 호출
- shouldComponentUpdate : 컴포넌트의 리렌더링 여부를 확인, true or false 반환, false시 작업 중지, 특정 함수에서
this.forceUpdate()
호출 시 과정 생략 후 바로 render호출- render: 컴포넌트 리렌더링
- getSnapshotBeforeUpdate : 컴포넌트 변화를 DOM에 반영하기 바로 직전에 호출 (이후 웹브라우저 상에 실제 DOM변화함)
- componentDidUpdate: 컴포넌트 업데이트 작업이 끝난 후 호출
언마운트
마운트의 반대, 컴포넌트를 DOM에서 제거하는 것
- componentWillUnmount: 컴포넌트가 웹브라우저 상에서 사라지기 전에 호출
컴포넌트의 라이프 사이클 메서드 흐름