한 걸음씩

[React] Custom Hooks, Refs and More state 본문

React

[React] Custom Hooks, Refs and More state

winter17 2024. 1. 27. 22:39

 

Rules of Hooks

  1. only call hooks at the top level
  2. only call hooks from React functions

 

 

 

Refs → 참조

 

useState와 useRef는 재렌더링 유무

 

재사용성↑ + Hooks 내부에 반드시 state or Effect가 있어야 함 + 이름은 반드시 'use'로 시작

 


# 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