Develop/React.js

[React]ref:DOM에 이름달기

dawonny 2021. 7. 18. 02:08
728x90
반응형

이 글은 [리액트를 다루는 기술](저자 김민준, 출판사 길벗) 교재를 보고 공부하며 정리한 글임.


html 에서 id를 사용하여 DOM에 이름을 다는 것처럼

리액트 프로젝트 내부에서 DOM에 이름을 다는 방법 -> ref

DOM이 뭐더라?

Document Object Model의 약어

객체로 문서 구조를 표현하는 방법

ref는 언제 사용해야할까? -> DOM을 직접적으로 건드려야 할때

함수형 컴포넌트에서 ref를 사용하려면 Hooks를 사용해야 함(뒤에서 나옴)


예제 컴포넌트

ValidationSample.css

.success{
    background-color: lightgreen;
}
.failure{
    background-color: lightcoral;
}

ValidationSample.js

import { findAllByTestId } from '@testing-library/react';
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;

App.js

import React, {Component} from 'react';
import ValidationSample from './ValidationSample';

class App extends Component{
    render(){
        return(
            <ValidationSample/>
        );
    }
}

export default App;

0000 을 입력했을때

그런데 이렇게 state 를 사용하는 걸로는

특정 input에 포커스주기

스크롤 박스 조작하기

Canvas 요소에 그림그리기 등

해결할 수 없는 기능들이 있다

따라서 이럴땐 DOM을 직접적으로 접근해야하고 이럴때 ref를 사용


ref 사용 방법은 2가지

1. 콜백함수를 통한 ref 설정

예시

<input ref={(ref) -> {this.input=ref}} />

2. createRef 를 통한 ref 설정

리액트에 내장되어 있는 createRef라는 함수를 사용하기


input에 ref 달기

<input
                ref={(ref) => this.input=ref}
//...

버튼 onClick 이벤트 발생하면 input에 포커스를 주도록 수정하기


컴포넌트에 ref 달기

<Mycomponent

ref={(ref) => {this.myComponent=ref}}

/>

이렇게 하면 MyComponent의 메서드와 멤버변수에 접근가능


ScrollBox 컴포넌트 만들기

ScrollBox.js

import React, {Component} from 'react';

class ScrollBox extends Component {
    render(){
        const style={
            border:'1px solid black',
            height:'300px',
            width:'300px',
            overflow:'auto',
            position:'relative'
        };

        const innerStyle = {
            widht:'100%',
            height:'650px',
            background:'linear-gradient(white, black)'
        }

        return(
            <div
            style={style}
            ref={(ref) => {this.box = ref}}>
                <div style={innerStyle}/>
            </div>
        );
    }
}

export default ScrollBox;

기존 ValidationSample 지우고

방금 만든 컴포넌트 렌더링 하기

App.js

import React, {Component} from 'react';
import ScrollBox from './ScrollBox';

class App extends Component{
    render(){
        return(
            <div>
                <ScrollBox/>
            </div>
        );
    }
}

export default App;

잘 렌더링 되었다

ScrollBox.js

import React, {Component} from 'react';

class ScrollBox extends Component {

//비구조화 할당 문법
    scrollToBottom=()=>{
        const{scrollHeight, clientHeight}=this.box;
        this.box.scrollTop = scrollHegiht - clientHeight;
    }

    render(){
        const style={
            border:'1px solid black',
            height:'300px',
            width:'300px',
            overflow:'auto',
            position:'relative'
        };

        const innerStyle = {
            widht:'100%',
            height:'650px',
            background:'linear-gradient(white, black)'
        }

        return(
            <div
            style={style}
            ref={(ref) => {this.box = ref}}>
                <div style={innerStyle}/>
            </div>
        );
    }
}

export default ScrollBox;

수정한 모습

이렇게 만든 메서드는 부모 컴포넌트인 App 컴포넌트에서 Scrollbox에 ref를 달면 사용할 수 있음


App.js

여기에 ScrollBox에 ref를 달고 버튼을 만들어 누르면 ScrollBox의 scrollToBottom 실행

import React, {Component} from 'react';
import ScrollBox from './ScrollBox';

class App extends Component{
    render(){
        return(
            <div>
                <ScrollBox ref={(ref)=>this.scrollBox=ref}/>
                <button onClick={()=>this.scrollBox.scrollToBottom()}>
                    맨 밑으로
                </button>
            </div>
        );
    }
}

export default App;

버튼을 눌렀더니 내려간 모습

 

728x90
반응형