Frontend/React
[React] useState 업데이트 값이 즉시 반영되지 않는 문제 (useState와 useRef)
반응형
1. 개요(문제)
- 사용자의 현재 위치를 받아와 지도에 표시하고자 했다.
- 초기 로직
- 위치 값
useState
로 초기화하기 navigator.geolocation.getCurrentPosition
API를 통해 현재 위치 가져오기- 받아온 값으로
state
업데이트하기
- 위치 값
- 하지만
useState
업데이트 값이 즉시 반영되지 않는 문제가 발생했다.
const Map = () => {
const [curLoc, setCurLoc] = useState({lat: 0, lng: 0});
const handleGeoSuccess = (pos) => {
const lat = pos.coords.latitude;
const lng = pos.coords.longitude;
const coordsObj = {
lat,
lng,
};
setCurLoc(...coordsObj);
};
...
useEffect(() => {
const getGeoLoc = () => {
if (!navigator.geolocation) {
alert('Geolocation is not supported by your browser');
} else {
navigator.geolocation.getCurrentPosition(
handleGeoSuccess,
handleGeoError
);
}
};
getGeoLoc();
}, []);
...
return (
...
<GoogleMap
mapContainerStyle={containerStyle}
center={curLoc}
zoom={10}
onLoad={onLoad}
onUnmount={onUnmount}
onClick={() => setActiveMarker(null)}
>
</GoogleMap>
...
};
export default Map;
2. 원인
useState
를 이용한 상태 업데이트는 비동기적이기 때문에 변경 사항이 즉시 반영되지 않는다.useState
의 업데이터는 이전 값을 기억(with 클로저
)하고 있다가, 비동기 요청에서 사용 가능한 값으로 바꾼다.- 함수형 컴포넌트는 상태변경이 일어나면 함수를 다시 호출해 렌더링을 해야한다.
- 즉,
useState
를 통해 업데이트할 때는 리렌더링이 필요하다.
3. 해결
useState
대신useRef
를 사용했다.useRef
는 업데이트 시 리렌더가 일어나지 않는 가변 값을 저장하는 데 사용할 수 있다.
const Map = () => {
const centerRef = useRef({ lat: null, lng: null });
const handleGeoSuccess = (pos) => {
const lat = pos.coords.latitude;
const lng = pos.coords.longitude;
const coordsObj = {
lat,
lng,
};
centerRef.current = coordsObj;
setIsGeoLoaded(true);
};
useEffect(() => {
const getGeoLoc = () => {
if (!navigator.geolocation) {
alert('Geolocation is not supported by your browser');
} else {
navigator.geolocation.getCurrentPosition(
handleGeoSuccess,
handleGeoError
);
}
};
getGeoLoc();
}, []);
...
return (
...
<GoogleMap
mapContainerStyle={containerStyle}
center={centerRef.current}
zoom={10}
onLoad={onLoad}
onUnmount={onUnmount}
onClick={() => setActiveMarker(null)}
>
</GoogleMap>
...
};
export default Map;
결과 이미지
사이트에 초기 접근 시 현재 위치인 K-SW Square가 바로 나오는 것을 확인할 수 있다.
참고) useRef
useRef
는JS DOM
에 직접 접근이 가능하다. 따라서 특정DOM
을 가리킬 때 사용한다.- 주로 대상에 대한 포커스 설정, 특정 엘리먼트의 크기나 색상을 변경할 때 사용한다.
- 즉, 리액트에서 컴포넌트의 특정 부분을 직접 선택할 수 있게 해주는 기능이다.
Reference
- https://www.wake-up-neo.com/ko/javascript/usestate-%EC%84%A4%EC%A0%95-%EB%A9%94%EC%86%8C%EB%93%9C%EA%B0%80-%EC%A6%89%EC%8B%9C-%EB%B3%80%EA%B2%BD-%EC%82%AC%ED%95%AD%EC%9D%84-%EB%B0%98%EC%98%81%ED%95%98%EC%A7%80-%EC%95%8A%EC%9D%8C/807713321/
- https://velog.io/@suuhyeony/React-useRef-useEffect
- https://www.w3schools.com/react/react_useref.asp
반응형
'Frontend > React' 카테고리의 다른 글
[React] CRA 프로젝트에 serviceWorker 적용하기 (0) | 2021.08.30 |
---|