한 걸음씩
[React] Custom Hooks, Refs and More state 본문
◆ Rules of Hooks
- only call hooks at the top level
- only call hooks from React functions
# challenge: useGeolocation
import { useState } from "react";
function useGeolocation() {}
export default function App() {
const [isLoading, setIsLoading] = useState(false);
const [countClicks, setCountClicks] = useState(0);
const [position, setPosition] = useState({});
const [error, setError] = useState(null);
const { lat, lng } = position;
function getPosition() {
setCountClicks((count) => count + 1);
if (!navigator.geolocation)
return setError("Your browser does not support geolocation");
setIsLoading(true);
navigator.geolocation.getCurrentPosition(
(pos) => {
setPosition({
lat: pos.coords.latitude,
lng: pos.coords.longitude
});
setIsLoading(false);
},
(error) => {
setError(error.message);
setIsLoading(false);
}
);
}
return (
<div>
<button onClick={getPosition} disabled={isLoading}>
Get my position
</button>
{isLoading && <p>Loading position...</p>}
{error && <p>{error}</p>}
{!isLoading && !error && lat && lng && (
<p>
Your GPS position:{" "}
<a
target="_blank"
rel="noreferrer"
href={`https://www.openstreetmap.org/#map=16/${lat}/${lng}`}
>
{lat}, {lng}
</a>
</p>
)}
<p>You requested position {countClicks} times</p>
</div>
);
}
[countClicks, setCountClicks] = useState(0), position을 제외한 나머지 코드를 useGeolocation 함수에 작성
App 컴포넌트에서 필요한 값들을 리턴 { isLoading, position, error, getPosition }
App 컴포넌트에서 useGeolocation 커스텀 훅을 불러와서 커스텀 훅에서 리턴한 값을 구조 분해 할당으로 작성
이후 handleClick 함수를 만들어 countClicks 값을 업데이트하고, getPosition함수를 실행하여 나의 현재 위치 값을 불러올 수 있게 함.
import { useState } from "react";
function useGeolocation() {
const [isLoading, setIsLoading] = useState(false);
const [position, setPosition] = useState({});
const [error, setError] = useState(null);
function getPosition() {
if (!navigator.geolocation)
return setError("Your browser does not support geolocation");
setIsLoading(true);
navigator.geolocation.getCurrentPosition(
(pos) => {
setPosition({
lat: pos.coords.latitude,
lng: pos.coords.longitude
});
setIsLoading(false);
},
(error) => {
setError(error.message);
setIsLoading(false);
}
);
}
return { isLoading, position, error, getPosition };
}
export default function App() {
const {
isLoading,
position: { lat, lng },
error,
getPosition
} = useGeolocation();
const [countClicks, setCountClicks] = useState(0);
function handleClick() {
setCountClicks((count) => count + 1);
getPosition();
}
return (
<div>
<button onClick={handleClick} disabled={isLoading}>
Get my position
</button>
{isLoading && <p>Loading position...</p>}
{error && <p>{error}</p>}
{!isLoading && !error && lat && lng && (
<p>
Your GPS position:{" "}
<a
target="_blank"
rel="noreferrer"
href={`https://www.openstreetmap.org/#map=16/${lat}/${lng}`}
>
{lat}, {lng}
</a>
</p>
)}
<p>You requested position {countClicks} times</p>
</div>
);
}
'React' 카테고리의 다른 글
[React] React-Router (0) | 2024.02.05 |
---|---|
[React] classy-weather project [미완] (0) | 2024.01.30 |
[React] Effects and Data Fetching (0) | 2024.01.27 |
[React] How React works (0) | 2024.01.26 |
[React] How react works behind the scenes (0) | 2024.01.26 |