uesRef는 component의 entire lifetime동안 지속되는 object를 생성한다. (component의 unmount까지 유지된다.)
하지만 obejct의 current 속성을 이용해 변수의 값에 접근할 수 있다.
useRef로 생성된 object는 state와 다르게 component의 re-render시에도 변하지 않는다. (re-render에 영향을 받지 않는다.)
import { useState,useRef } from "react";
export default function MyComponent_19_1(){
const [count,SetCount] = useState(0)
const countRef = useRef(0)
let countVar = 0
const incrementCountState = () => {
SetCount(count + 1)
}
const incrementCountRef = () => {
countRef.current = countRef.current + 1
}
const incrementCountVar = () => {
countVar = countVar + 1
}
return(
<div>
<p>State: {count}</p>
<p>Ref: {countRef.current}</p>
<p>Var: {countVar}</p>
<button onClick={incrementCountState}>State 증가</button>
<button onClick={incrementCountRef}>Ref 증가</button>
<button onClick={incrementCountVar}>Var 증가</button>
</div>
)
}
위의 예제 코드에서 State 증가 버튼이 클릭되면 incrementCountState 함수에서 setCount가 실행된다.
이 때 state가 변경되었기 때문에 component는 re-render된다.
Ref 증가 버튼이 클릭되면 incrementCountRef 함수에서 countRef의 current 속성의 값이 1 증가한다.
이 때 component는 re-render되지 않으므로 <p> element 안의 countRef.current 값은 변하지 않는다. (실제로는 바뀌지만 화면에 보여지지 않음)
component가 re-render될 시 이전의 값이 남아있기 때문에 값이 계속 더해진다.
Var 증가 버튼이 클릭되면 incrementCountVar 함수에서 countVar의 값이 1 증가한다.
하지만 component는 re-render되지 않으므로 <p> 안의 countVar는 변하지 않는다.
component가 re-render될 시 countVar 변수도 함께 0으로 초기화된다.
useRef는 re-render에 영향을 받지 않으면서 값에 접근할 수 있는 Object를 생성한다.
또한 useRef로 만들어진 current의 값이 바뀔 때 component는 re-render되지 않는다.
import { useState,useRef,useEffect } from "react";
export default function MyComponent_19_2(){
const [count,setCount] = useState(0)
const [renderCount,setRenderCount] = useState(0)
const renderRef = useRef(0)
// 의존성 배열이 생략되었으므로 컴포넌트 업데이트시마다 실행
// 생성시 초기값 0, 생성후 실행되므로 1
useEffect(()=>{
// console.log('렌더링:',renderCount)
// setRenderCount(renderCount+1)
console.log('렌더링:',renderRef.current)
renderRef.current = renderRef.current + 1
})
return(
<div>
<p>State: {count}</p>
<p>render State: {renderCount}</p>
<p>Ref: {renderRef.current}</p>
<button onClick={() => setCount(count + 1)}>State Count 증가</button>
</div>
)
}
위의 코드에서 useEffet는 component의 render마다 실행된다.
만약 setRenderCount를 useEffect 안에서 사용하면 state가 바뀌므로 componenet를 rerender한다.
이것은 useEffect를 다시 실행시키므로 결국 renderCount의 값은 무한으로 증가한다.
이 때 setRenderCount 대신 ref 변수의 값을 1 증가시킨다면 이것은 rerender를 발생시키지 않으므로 정상적으로 작동한다.
변화는 감지해야 하지만 그 변화가 랜더링을 발생시키면 안되는 경우 사용할 수 있다.
useRef의 쓰임 by ChatGPT
- Accessing DOM elements: You can use useRef to get references to DOM elements and interact with them imperatively. This can be useful for focusing elements, measuring their dimensions, or animating them.
- Storing mutable values: useRef can store values that persist across renders without causing re-renders. This is useful for storing values that you want to persist between renders but don't need to be part of the component's state.
- Keeping track of previous values: You can use useRef to store values that need to persist across renders for comparison purposes. This is often used in useEffect hooks to compare previous and current values.
- Optimizing performance: In some cases, useRef can be used to optimize performance by memoizing values or references that don't need to trigger re-renders.
- Caching expensive computations: You can use useRef to cache the result of expensive computations so that they don't need to be recomputed on every render.
- Storing mutable data for third-party libraries: If you're using a third-party library that requires mutable data, you can use useRef to store that data without triggering re-renders.
3의 예제
import React, { useEffect, useRef, useState } from "react";
function Example() {
const [count, setCount] = useState(0);
const countRef = useRef(0);
useEffect(() => {
// Store the current count in the ref before it changes
countRef.current = count;
// Log the previous and current count
console.log("Previous count:", countRef.current);
console.log("Current count:", count);
}, [count]);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
}
export default Example;
5의 예제
ㅑmport React, { useEffect, useRef, useState } from "react";
function Example() {
const [count, setCount] = useState(0);
const [result, setResult] = useState(null);
const computationCache = useRef({});
useEffect(() => {
// Check if the result for the current count is already cached
if (computationCache.current[count] !== undefined) {
// If it's cached, use the cached result
setResult(computationCache.current[count]);
} else {
// If it's not cached, perform the expensive computation
const computedResult = expensiveComputation(count);
// Cache the result for future use
computationCache.current[count] = computedResult;
// Update the result state
setResult(computedResult);
}
}, [count]);
// Example of an expensive computation function
function expensiveComputation(input) {
console.log("Performing expensive computation for input:", input);
// Simulate an expensive computation
return input * 2;
}
return (
<div>
<p>Count: {count}</p>
<p>Result of Expensive Computation: {result}</p>
<button onClick={() => setCount(count + 1)}>Increment Count</button>
</div>
);
}
export default Example;
'Front-end > React' 카테고리의 다른 글
Zustand 사용 (0) | 2024.04.04 |
---|---|
Axios로 서버에 http 요청 보내기 (1) | 2024.04.02 |