[React] Ref (Props의 한 종류)

2022. 6. 13.공부/React

728x90

 

책이나 강의를 살펴보면서 Ref에 대하여 두 가지 정도로 정리할 수 있었다. "1) 돔 요소를 선택할 수 있는 기능이다. 2) 값 변화가 일어나지만, state와는 달리 변화 시 re-render가 일어나지는 않는다." 

 

1) Ref값을 이용해서 돔 요소를 선택할 수 있다. useRef()를 이용해서 지역 변수를 선언한 뒤, HTML 태그에 ref를 지정해주면 해당 HTML 태그와 선언한 Ref의 값이 연결된다. ref의 current 속성을 이용하면 엘리먼트를 제어할 수 있으며, 보통 input 엘리먼트와 audio 파일에 current 속성이 자주 사용된다.

 

import { useState, useRef } from "react";

const DiaryItem = ({    
    onEdit,
    onRemove,
    id, 
    author, 
    content, 
    emotion, 
    created_date,
    }) => {
    const [isEdit, setIsEdit] = useState(false);
    const toggleIsEdit = () => setIsEdit(!isEdit);

    const [localContent,setLocalContent] = useState(content);
    const localContentInput = useRef();

    const handleRemove = () => {
        if(window.confirm(`${id}번째 일기를 정말 삭제하시겠습니까?`)) {
            onRemove(id); 
        }
    };

    const handleQuitEdit = () => {
        setIsEdit(false);
        setLocalContent(content);
    };

    const handleEdit = () => {
        if(localContent.length < 5) {
            localContentInput.current.focus();
            return;
        }

        if(window.confirm(`${id}번 째 일기를 수정하시겠습니까?`)) {
            onEdit(id,localContent);
            toggleIsEdit();
        }
    };

    return (
    <div className="DiaryItem">
        <div className="info">
            <span className="author_info">
                <strong className="tit">작성자 :</strong> {author} | 
                <strong className="tit">감정점수</strong> : {emotion}
            </span>
            <br />
            <span className="date">
                {new Date(created_date).toLocaleString()}
            </span>
        </div>
        <div className="content">
            {isEdit ? (
            <>
                <textarea 
                ref={localContentInput}
                value={localContent} 
                onChange={(e) => setLocalContent(e.target.value)} />
            </>
            ) : (
            <>{content}</>
            )}
        </div>


        {isEdit ? <>
            <button onClick={handleQuitEdit}>수정 취소</button>
            <button onClick={handleEdit}>수정 완료</button>
        </> : 
        <>
            <button onClick={handleRemove}>삭제하기</button>
            <button onClick={toggleIsEdit}>수정하기</button>
        </> }
        
    </div>
    );
};

export default DiaryItem;

 

2) Ref를 이용해서 초기값을 지정하고,  변수명.current를 사용하여 호출할 수 있다. 게시판에 글을 추가하는 기능 구현 시 dataId를 Ref로 선언하고 글이 하나 생성될 때마다 변수명.current에 +1씩 더해주었다. 

 

게시글 추가 기능을 구현하기 위한 동적 변수의 용도로 Ref를 사용하였다. 초기값은 0

 

함수형 컴포넌트에서의 ref 생성 

useRef() 메소드 사용

const localContentInput = useRef();

 

클래스형 컴포넌트에서의 ref 생성
<input ref={(ref)=> {this.input.ref}}/>

 

혹은

const REF = React.createRef();

 

 

정리해보자면

  • state와 props처럼 상태 변화가 일어나면서도 변화 시 리랜더가 일어나지 않는다.
  • Ref 변수는 참조값을 저장하고 있다. 또, current라는 메소드를 가지고 있어서 이 메소드를 통해 DOM에 접근하여 조작할 수 있다.
  • Ref로 변수를 선언하면 초기값을 지정할 수 있다.