일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 컬렉션 타입
- 예외미루기
- 생성자오버로드
- NestedFor
- 어윈 사용법
- 컬렉션프레임워크
- EnhancedFor
- 예외처리
- 집합_SET
- 추상메서드
- 인터페이스
- 객체 비교
- oracle
- 정수형타입
- 자바
- 대덕인재개발원
- 오라클
- 제네릭
- exception
- Java
- 한국건설관리시스템
- abstract
- cursor문
- 자동차수리시스템
- 다형성
- 사용자예외클래스생성
- GRANT VIEW
- 참조형변수
- 메소드오버로딩
- 환경설정
- Today
- Total
거니의 velog
(13) ref:DOM 에 이름 달기 1 본문
* 일반 HTML에서 DOM 요소에 이름을 달 때는 id를 사용한다.
* DOM 요소의 id
<div id="my-element"></div>
* 특정 DOM 요소에 어떤 작업을 해야 할 때 이렇게 요소에 id를 달면 CSS에서 특정 id에 특정 스타일을 적용하거나 자바스크립트에서 해당 id를 가진 요소를 찾아서 작업할 수 있다. 우리가 다루는 리액트 프로젝트에서 사용하는 public/index.html 파일에도 id가 root인 div 요소가 있다.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="description" content="Web site created using create-react-app"/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<title>React App</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>
* 그리고 src/index.js 파일 중에는 id가 root인 요소에 리액트 컴포넌트를 렌더링하라는 코드가 있다.
const root = ReactDOM.createRoot(document.getElementById('root'));
* 이렇게 HTML에서 id를 사용하여 DOM에 이름을 다는 것처럼 리액트 프로젝트 내부에서 DOM에 이름을 다는 방법이 있다. 바로 ref (reference 의 줄임말) 개념이다.
* 리액트 컴포넌트 안에서는 id를 사용하면 안 되나요?
- 리액트 컴포넌트 안에서도 id를 사용할 수 있다. JSX 안에서 DOM에 id를 달면 해당 DOM을 렌더링할 때 그대로 전달한다.
하지만 특수한 경우가 아니면 사용을 권장하진 않는다. 예를 들어 같은 컴포넌트를 여러 번 사용한다고 가정해 보자.
HTML에서 DOM의 id는 유일(unique)해야 하는데, 이런 상황에서는 중복 id를 가진 DOM이 여러 개 생기니 잘못된 사용이다.
ref는 전역적으로 작동하지 않고 컴포넌트 내부에서만 작동하기 때문에 이런 문제가 생기지 않는다.
대부분은 id를 사용하지 않고도 원하는 기능을 구현할 수 있지만, 다른 라이브러리나 프레임워크와 함께 id를 사용해야
하는 상황이 발생할 수 있다. 이런 상황에서는 컴포넌트를 만들 때마다 id 뒷부분에 추가 텍스트를 붙여서
(예:button01 button02 button03 ... ) 중복 id가 발생하는 것을 방지해야 한다.
1. ref는 어떤 상황에서 사용해야 할까?
* 먼저 ref는 어떤 상황에서 사용해야 하는지 제대로 짚고 넘어가 보자. 일단 특정 DOM에 작업을 해야 할 때 ref를 사용한다는 것은 이미 파악했다. 하지만 대체 '어떤' 작업을 할 때 ref를 사용해야 할까?
* 정답은 'DOM을 꼭 직접적으로 건드려야 할 때' 이다. 예를 들어 일반 순수 자바스크립트 및 jQuery로 만든 웹 사이트에서 input을 검증할 때는 다음과 같이 특정 id를 가진 input 클래스를 설정해 준다.
https://jsbin.com/?html,output
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>Example</title>
<style>
.success {
background-color: green;
}
.failure {
background-color: red;
}
</style>
<script>
function validate(){
var input = document.getElementById('password');
input.className = '';
if(input.value === '0000') {
input.className = 'success';
}else {
input.className = 'failure';
}
}
</script>
</head>
<body>
<input type="password" id="password" />
<button type="button" onclick="validate()">Validate</button>
</body>
</html>
* 하지만 리액트에서 이런 작업은 굳이 DOM에 접근하지 않아도 state로 구현할 수 있다. 잘 이해가 되지 않을 것이나, 앞으로 작성할 예제 코드를 확인해 보면 감이 올 것이다. 리액트 컴포넌트에서 state를 사용하여 제시한 기능을 한번 구현해 보자.
* 이 장에서는 클래스형 컴포넌트에서 ref를 사용하는 방법을 알아보자. 함수형 컴포넌트에서 ref를 사용하려면 Hooks를 사용해야 하기 때문에 이후에 Hooks를 배우면서 알아볼 것이다.
* 이번 실습은 다음 흐름으로 진행한다.
(1) 예제 컴포넌트 생성
* src 디렉터리 안에 ValidationSample.css와 ValidationSample.js 파일을 만들어 주자.
[ValidationSample.css]
.success {
background-color: lightgreen;
}
.failure {
background-color: lightcoral;
}
[ValidationSample.js]
import React, { Component } from 'react';
import './ValidationSample.css';
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;
* input에서는 onChange 이벤트가 발생하면 handleChange를 호출하여 state의 password 값을 업데이트하게 했다. button에서는 onClick 이벤트가 발생하면 handleButtonClick을 호출하여 clicked 값을 참으로 설정했고, validated 값을 검증 결과로 설정했다.
* input의 className 값은 버튼을 누르기 전에는 비어 있는 문자열을 전달하며, 버튼을 누른 후에는 검증 결과에 따라 success 값 또는 failure 값을 설정한다. 그리고 이 값에 따라 input 색상이 초록색 또는 빨간색으로 나타난다.
(2) App 컴포넌트에서 예제 컴포넌트 렌더링
* App 컴포넌트에서 ValidationSample 컴포넌트를 불러와 렌더링해 보자. 그 과정에서, App 컴포넌트를 함수형 컴포넌트에서 클래스형 컴포넌트로 전환해 주자. 우리가 추후 App 컴포넌트에서 ref를 사용할 것이기 때문에 이렇게 미리 클래스형 컴포넌트로 작성해 줄 것이다.
import React, { Component } from 'react';
import ValidationSample from './ValidationSample';
class App extends Component {
render() {
return <ValidationSample />;
}
}
export default App;
* 코드를 저장하고, 다음 결과물이 나타나는지 확인해 보자.
(3) DOM을 꼭 사용해야 하는 상황
* 앞 예제에서는 state를 사용하여 우리에게 필요한 기능을 구현했지만, 가끔 state 만으로 해결할 수 없는 기능이 있다. 어떤 상황인지 알아보자.
- 특정 input에 포커스 주기
- 스크롤 박스 조작하기
- Canvas 요소에 그림 그리기 등
* 이떄는 어쩔 수 없이 DOM에 직접적으로 접근해야 하는데, 이를 위해 바로 ref를 사용한다.
'React_리액트 시작' 카테고리의 다른 글
(15) 컴포넌트 반복 1 (0) | 2023.12.01 |
---|---|
(14) ref:DOM 에 이름 달기 2 (0) | 2023.11.30 |
(12) 이벤트 핸들링 2 (0) | 2023.11.30 |
(11) 이벤트 핸들링 1 (2) | 2023.11.30 |
(10) 컴포넌트 3 (0) | 2023.11.29 |