<출처>
컴포넌트에서 특정 DOM을 사용 지정해 사용할 때 ref
를 사용합니다.
그리고 함수형 컴포넌트에서 이를 설정할 때, useRef
를 사용합니다.
useRef
Hook은 DOM을 선택하는 용도 외에도 다른 용도가 있는데, 이는 컴포넌트 안에서 조회 및 수정을 할 수 있는 변수를 관리하는 것입니다.
useRef
로 관리하는 변수는 값이 바뀐다고 컴포넌트가 재렌더링 되지 않습니다.
리액트 컴포넌트에서의 상태는 상태를 바꾸는 함수를 호출하고나서 그 다음 렌더링 이후로 업데이트 된 상태를 조회할 수 있는 반면, useRef
로 관리하고 있는 변수는 설정 후 바로 조회할 수 있습니다.
다음과 같은 값을 관리할 수 있습니다.
setTimeout
, setInterval
을 통해서 만들어진 id
이 글에서는 App 컴포넌트에서 useRef
를 사용하여 변수를 관리해보겠습니다.
useRef
를 사용하여 변수를 관리하기 전에 해야 할 작업이 있습니다.
지금은 우리가 UserList 컴포넌트 내부에서 배열을 직접 선언해서 사용을 하고 있는데, 이렇게 UserList에서 선언해서 사용하는 대신, 이 배열을 App에서 선언하고 UserList에게 props로 전달해주겠습니다.
기존 HTML 문서 작성에서 자바스크립트로 해당 객체를 연결하려면 태그 안에 id값을 주거나 class 값을 주어
id
');#class
');리액트는 태그 안에 ref값을 지정하여 해당 ref값을 사용하여 해당 객체를 지정할 수 있습니다.
// HTML Document <input ref={ImNameInput}`\>
// Javascript ImNameInput.current.focus();
여기서 current
는 우리가 사용하고자하는 DOM을 나타냅니다.
다음과 유사합니다
console.log(e); // 이벤트 발생 객체 태그 출력 // input 출력 console.log(ImNameInput); // 이벤트 발생 객체 태그 출력 // input 출력. console.log(e.target); // 이벤트 발생 객체 지정 출력 // input name='name' value='aaa' ... console.log(ImNameInput.current); // input name='name' value='aaa' ...
그럼, 다음과 같이
import React from "react"; import './App.css' function User( {user, onRemove } ) { return ( <div> <b>{user.username}</b> <span>({user.email})</span> </div> ); } function UserList( {users} ) { return ( <div> { users.map(user => ( <User user={user} key={user.id}/> )) } </div> ); } export default UserList;
import './App.css'; import React, {useRef, useState} from 'react'; import UserList from './UserList'; import CreateUser from './CreateUser'; import InputSample from './InputSample'; function App() { const [inputs, setInputs] = useState ({ username: '', email: '' }) const {username, email} = inputs; const onChange = (e) => { const {name, value} = e.target; setInputs( { ...inputs, \[name]: value }); } const [users, setUsers] = useState ([ { id: 1, username: 'velopert', email: 'public.velopert@gmail.com' }, { id: 2, username: 'tester', email: 'tester@example.com' }, { id: 3, username: 'liz', email: 'liz@example.com' } ]); const nextId = useRef(4); const onCreate = ()=> { const user = { id: nextId.current, username, email }; setUsers([...users, user]); setInputs({ username: '', email: '' }) } return ( <div className='container'> <div className='basic'> <CreateUser username={username} email={email} onChange={onChange} onCreate={onCreate}/> </div> <div className='usrlist'> <UserList users={users} /> </div> </div> ) } export default App;
다음과 같이 코드를 작성하면
위와 같은 모습으로 출력이 됩니다.
(css를 건드린 상태입니다.)
App.js 코드에서 이미 배열에 3가지의 목록이 들어가있고, 각 컴포넌트의 key값을 id값으로 물려주었기 때문에 nextId를 useRef
를 이용하여 id의 시작값을 4로 주었습니다.
const [변수명] = useRef(Value)
Value(파라미터)값을 current의 값으로 지정.
현재 nextId를 변수명으로 지었는데
이를 console.log(nextId)
로 출력하면
// 등록 클릭
current:{5} (현재 id에서 +1한 값)
// 등록 클릭
current:{6} (현재 id에서 +1한 값)
이를 comsole.log(nextId.current)
한다면
// 등록 클릭
5
// 등록 클릭
6
위와 같이 출력되게 됩니다. 자동으로 id값이 1이 증가하여 적용됩니다.
Ref를 사용하는 경우는 다음과 같습니다.