useRef
: use + Reference(참조)
- 변경 가능한 참조 객체를 생성할 수 있는 기능(훅)
사용 목적
- DOM 요소에 직접적으로 접근하고 조작
- 컴포넌트가 재렌더링될 때도 값이 유지되는 변수 관리
- 이전 상태를 기억 (렌더링 사이에 지속되는 값을 유지)
기본 문법
const refContainer = useRef(initialValue)
- initialValue: 참조 객체의 초기값
- refContainer.current: 저장된 현재 값에 접근
추가내용
더보기
useRef는 객체를 반환
- 해당 객체에는 current라는 속성이 존재
- 컴포넌트의 재렌더링에도 값이 유지
(예제 코드)
더보기
export default function UseRef01() {
const [text, setText] = useState<string>('');
const lengthRef = useRef(0);
// let lengthData = 0;
const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
setText(e.target.value);
lengthRef.current = e.target.value.length;
// lengthData = e.target.value.length;
}
return (
<div>
<h4>현재 텍스트 길이 측정 예제</h4>
<input type="text" value={text} onChange={handleInputChange} />
<p>Text길이: {lengthRef.current}</p>
{/* <p>{lengthData}</p> */}
</div>
)
}
useRef를 사용한 DOM 요소 참조
- 컴포넌트가 재렌더링 되더라도 동일한 참조값을 유지
- 특정 DOM 요소에 접근하고 조작
더보기
export default function UseRef02() {
const [count, setCount] = useState<number>(0);
const inputRef = useRef<HTMLInputElement>(null);
const prevCountRef = useRef<number>(0)
const handleButtonFocus = () => {
// 'current'는 참조하는 DOM 요소를 나타냄
if (inputRef.current) {
// .focus(): DOM 요소를 활성화
inputRef.current.focus();
}
};
const incrementCount = () => {
setCount((prevcount) => {
prevCountRef.current = prevcount;
return prevcount + 1;
});
};
return (
<div>
<input type="text" ref={inputRef} />
<button onClick={handleButtonFocus}>Focus the input</button>
<hr />
<p>현재 카운트: {count}</p>
<p>이전 카운트: {prevCountRef.current}</p>
<button onClick={incrementCount}>증가</button>
</div>
);
}
배열 렌더링(추가, 조회, 수정, 삭제 - CRUD)
- 해당 과정에서 배열 내부의 각 요소를 구분 지을 id 값이 필요
(예제 : 장바구니 구현)
더보기
// 장바구니의 타입 정의
interface IItem {
id: number;
name: string;
amount: number;
}
// 기존 장바구니 목록
const initialItems: IItem[] = [
{ id: 1, name: "사과", amount: 2 },
{ id: 2, name: "칸쵸", amount: 3 },
{ id: 3, name: "우유", amount: 1 },
];
//# 자식 컴포넌트
// : 장바구니 항목 1개
// >> 부모로 부터 각 아이템을 인자로 받아 하나의 장바구니 항목을 생성
interface IItemProps {
item: IItem;
}
// function Item({ item }: { item: IItem }) {}
function Item({ item }: IItemProps) {
return (
<div>
<p>
<b>{item.name}</b>
amount: {item.amount}
</p>
</div>
);
}
//! useRef를 사용한 고유한 id값 생성
//# '각 아이템'을 보여주는 컴포넌트
// : 수정, 삭제 기능 포함
// 컴포넌트 props 타입 정의
interface ItemComponentProps {
item: IItem; // id, name, amount
onRemove: (id: number) => void;
onUpdate: (id: number, amount: number) => void;
}
const ItemComponent = ({ item, onRemove, onUpdate }: ItemComponentProps) => {
return (
<div>
<strong>{item.name}</strong>
<input
type="number"
value={item.amount}
onChange={(e) => onUpdate(item.id, Number(e.target.value))}
/>
<button onClick={() => onRemove(item.id)}>삭제</button>
</div>
);
};
//# 부모 컴포넌트
export default function UseRef03() {
const [items, setItems] = useState<IItem[]>(initialItems);
// useRef
// >> 컴포넌트가 리렌더링 되더라도 해당 값은 유지
// const 참조값을 담을 변수 = useRef<데이터의타입>(초기값);
const nextId = useRef<number>(4);
//? 새로운 아이템을 생성하는 함수
const handleCreateItem = (name: string, amount: number) => {
const newItem = {
id: nextId.current,
name,
amount,
};
setItems([...items, newItem]);
nextId.current ++;
};
//? id와 수량을 전달받아 데이터를 수정하는 함수
const handleUpdateAmount = (id: number, amount: number) => {
setItems(
items.map((item) => (item.id === id ? { ...item, amount } : item))
);
};
//? id값을 전달 받아 삭제하고자 하는 요소를 filtering하는 함수
const handleRemove = (id: number) => {
setItems(items.filter((item) => item.id !== id));
};
return (
<div>
{/*
<Item item={initialItems[0]} />
<Item item={initialItems[1]} />
<Item item={initialItems[2]} />
*/}
{/*
{initialItems.map((item, index) => (
// map과 filter 사용 시 생성되는 컴포넌트 또는 요소에는
// , 각각을 구분할 수 있는 key값을 전달!
<Item item={item} key={index} />
))}
*/}
{initialItems.map((item) => (
// map과 filter 사용 시 생성되는 컴포넌트 또는 요소에는
// , 각각을 구분할 수 있는 key값을 전달!
// 배열 안의 객체 데이터는 각 데이터를 구분할 수 있는
// : 고유하고 변화되지 않는 id값 사용을 권장
<Item item={item} key={item.id} />
))}
<hr />
<button onClick={() => handleCreateItem("새로운 항목", 1)}>
새 항목 추가
</button>
<>
{items.map((item) => (
<div key={item.id}>
<ItemComponent
item={item}
onRemove={handleRemove}
onUpdate={handleUpdateAmount}
/>
</div>
))}
</>
</div>
);
}
'React' 카테고리의 다른 글
[React] Hooks - useCallback + useMemo (0) | 2024.09.06 |
---|---|
[React] Hooks - useEffect (0) | 2024.08.31 |
[React] Hooks - useState (0) | 2024.08.31 |
[React] Handler (0) | 2024.08.29 |
[React] Rendering (0) | 2024.08.29 |