본문 바로가기

웹 개발/React

React) Hooks : useRef

Hooks : useRef


useRef는 함수형 컴포넌트에서 ref를 쉽게 사용할 수 있도록 해줍니다. 

아래 예제에서 register 버튼을 눌렀을 때 포커스가 input으로 넘어가는 코드를 작성했습니다. 

 


  • view

여기서 input에 숫자를 입력하고 register 버튼을 누르면 바로 직후에 아래와 같이 input으로 포커스가 넘어갑니다.

  • example source code
import React, { useState, useMemo, useCallback, useRef } from 'react';

const getAverage = list => {
    console.log('평균값 계산 중...');
    if (list.length===0) return 0;
    const sum = list.reduce((a,b) => a+b);
    return sum/list.length;
}

const Average = () => {
    const [list,setList] = useState([]);
    const [number, setNumber] = useState('');
    const inputElement = useRef(null);

    // 처음 렌더링될 때만 함수 생성 
    const handleChange = useCallback( e => {setNumber(e.target.value)}, []);
    const handleKeyPress = e => {
        if (e.key === 'Enter') {
            handleClick();
        }
    }
    // number or list가 바뀌었을 때만 함수 생성 
    const handleClick = useCallback(e => {
        const newList = list.concat(parseInt(number));
        setList(newList);
        setNumber('');
        inputElement.current.focus();
    },[number,list]);

    const avg = useMemo(() => getAverage(list), [list]);
    
    
    return(
        <div>
            <h1>Hooks practice</h1>
            <input 
                value={number} 
                onChange={handleChange}
                onKeyPress={handleKeyPress}
                ref={inputElement}
            />
            <button onClick={handleClick}>register</button>
            <ul>
                {list.map((item,i) => <li key={i}>{item}</li>)}
            </ul>
            <div>average: {avg}</div>
        </div>
    );
}

export default Average;

 

 

 

inputElement 라는 변수를 useRef로 초기화해주고, 

const inputElement = useRef(null);

ref로 사용할 DOM인 input 의 ref attribute에 inputElement 값을 줍니다.

<input 
	value={number} 
    onChange={handleChange} 
    onKeyPress={handleKeyPress}
    ref={inputElement}
/>

그리고 handleClick 함수에서 useRef로 만든 객체 안의 current 값이 실제 요소를 직접 가리키게 되고, 여기에 focus()를 하게 하면 됩니다.

const handleClick = useCallback(e => {
        const newList = list.concat(parseInt(number));
        setList(newList);
        setNumber('');
        inputElement.current.focus();
    },[number,list]);

References

  • 리액트를 다루는 기술 (김민준)