개인 프로젝트 - 날씨 앱 (2) 현재 위치의 날씨 받아오기 (메인페이지구성)

개인 프로젝트 - 날씨 앱 (1) 현재 위치 받아오기날씨앱 메인페이지에서 구현 할 내용이, 내가 있는 위치의 날씨 정보 이므로, 현재 위치를 우선 알아야 한다.그 과정에 필요한 내용.날씨 앱 말고

creamymood.tistory.com

앞 게시글에서 이어집니다.

 


앞 게시글에서, 메인페이지에서의 현재 지역 위치 날씨 칸은 구현 완료 했다.

 

 

해당 게시글에서의 구현 목표는

1.(7)~(9)번 특정 나라의 온도 API를 받아온 뒤 렌더링 한다.

2. 예쁘지 않은 css..니까, 더 자주 쳐다보고 싶게 조금은 디자인적 요소를 추가해본다.

3. (11)번의 도시 검색창을 만들어준다.


1. 특정 나라의 온도 API를 받아온 뒤 렌더링

우선, OpenWeather 사이트에서, 특정 도시의 날씨 정보를 받아올 수 있었다.

 

두가지 방법이 있었는데 ❶ 도시 이름을 직접 넣어주기 ❷ 도시 ID 사용하기 (파일을 제공한다.).

 

우선 ❶번 방법으로, 테스트를 해본 뒤, 추후 검색 기능에서 ❷ 사용 해봐야겠다.


 

 

❶ 도시 이름으로 요청하기

 

위의 사진을 참고해서, api 호출을 하여 화면에 렌더링 해본다.

도쿄로 도시 이름에 넣어줘서 호출하니, 아래처럼 떴다.

 

 

코드는 다음과 같다.

더보기
 //도시 이름으로, 날씨 호출하기 함수
 const [tokyoWeather, setTokyoWeather] = useState(null)
 
 
    const cityWeather = async() => {
        const key = import.meta.env.VITE_WEATHER_KEY
        const url = `https://api.openweathermap.org/data/2.5/weather?q=Tokyo&appid=${key}`

        try{
          const response = await fetch(url)
          const data = await response.json()
          console.log(data)
          setTokyoWeather(data)

        }
        catch (error){
            console.error('도시 날씨 데이터를 불러오지 못했습니다:', error);
        }
    }

    //
    useEffect(() => {
      cityWeather()
    }, []);

 

return (
 	{tokyoWeather ? (
                <p>{`도쿄의 현재 날씨는 ${tokyoWeather.weather[0].description}`}</p>
            ) : (
                <p>도쿄 날씨 정보를 불러오는 중...</p>
                
            )}
)

 

 


 

2. 세 나라의 온도 API를 받아온 뒤 렌더링 (도시 공통 컴포넌트 방법)

나의 UI 목표는 3개의 나라를 구성 보여주는 것 이었으니까, 3개 다 이렇게 하나 하나 만들 수 있긴 하지만..

다른 블로그에서 배열로써 관리하는 방법을 참고 해서 한번 해보겠다.

원하는 나라 3개를 배열로써 만들어주고 map으로 돌려보겠음!

 

→ 해당 방식은 어떻게 우여곡절이 많아서 조교님이 추천해주신 방식으로 해보기로 했다

 

도시 공통 컴포넌트를 만들고, 배열의 도시를 프롭스(?매개변수)로 내려줘서, 배열을 맵돌리면

배열에 도시마다 도시 컴포넌트가 생기고 (예를 들어 : <City/> <City/> <City/>), 공통 컴포넌트 그 쪽에서 API를 부르는 방식으로!

 

2-1. 공통 도시 컴포넌트 만들기

도시 배열은 

    const cities = ['Tokyo', 'Busan', 'Toronto']

 

이렇게 만들어 두었고, 

내부에 도시정보가 들어오면, API를 호출 할 수 있게 호출 함수 그대로 사용

function Cities ({city}) {
    const [cityWeatherData, setCityWeatherData] = useState(null)

 //도시 이름으로, 날씨 호출하기 함수
    const cityWeather = async() => {
        const key = import.meta.env.VITE_WEATHER_KEY
        const url = `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${key}`

        try{
          const response = await fetch(url)
          const data = await response.json()
          console.log(data)
          setCityWeatherData(data)

        }
        catch (error){
            console.error('도시 날씨 데이터를 불러오지 못했습니다:', error);
        }
    }

    
    useEffect(() => {
      cityWeather()
    }, []);


    return(
        
        <div>
            {cityWeatherData? (
            <>
            <p>{`현재 위치는 : ${cityWeatherData.name}`}</p>
            <p>{`현재 날씨는 : ${cityWeatherData.weather[0].description}`}</p> 
            </>
            ) : (
                <p>날씨 정보를 불러오는 중...</p>
                
            )}
           
        </div>
    )

}

export default Cities

 

2-2. Home.jsx에서 배열을 map으로 돌리기

그리고, home.jsx에서는

           	{cities.map((city,index)=>(
                <Cities key={index} city={city}/>
            ))}

이렇게 배열을 맵으로 돌려서 <Cities />  <Cities />  <Cities /> 이렇게 세개가 뜰겁니다:)

 

간단했어!

 

이렇게 되었네요 !

 

 


디자인 적 요소를 조금은 가꿔야 할 것 같아서, 한번 다듬어 본다.


3. 특정 도시 날씨를 검색할 수 있는 검색창 만들기

도시 검색을 할 수 있는 검색창도 만들어줍니다.

 

3-1 Input창을 만들어서 버튼을 누르면 -> 디테일 페이지로 이동 하게 한다.

 

  ❶ return 안에, 이렇게 넣어줬고

<input placeholder="어느 도시가 궁금하세요?"/>

 

❷ 버튼을 달아서, detail로 넘어가게 했다.

그런데 버튼을 버튼 대신에, 리액트 라이브러리 중 하나인 아이콘을 사용해서 활용해봤다.

 

사용법은 다음과 같고,

 <input placeholder="어느 도시가 궁금하세요?"/> <Link to ="/detail"><IoIosSearch /></Link>

 

난 링크를 달아줬다!

 

*추가 수정 + 다음 단계에서 수정 했습니다.

더보기

해당 부분은, 인풋창에 값으로 버튼을 눌렀을 때, 그 값으로 url을 이동하려고 하는거기 때문에..

Link가 아닌 Onclick으로 바꿔줬다.

 

설명은 아래와 같음

상황 정리

지금 하고 싶은 건:

사용자가 입력창에 도시 이름을 입력하면,
그 값(/detail/입력값)으로 이동하고 싶다.
이동은 버튼(아이콘)을 눌렀을 때 일어나야 한다.

 Link를 쓰지 않고 navigate를 쓰는 이유

<Link>는 고정된 경로로 이동할 때 유용하다.

  • 예: <Link to="/about">About</Link>
  • 근데 사용자가 입력한 값에 따라 URL이 달라질 경우, <Link>의 to 속성에 동적으로 값 넣기 어렵거나 복잡해짐.
  • 그래서 onClick으로 navigate()를 호출해서 동적으로 이동시키는 게 자연스러움.

코드 확인

const inputChange = (e) => {
  setSearchInputValue(e.target.value)
}

const buttonChange = () => {
  navigate(`/detail/${searchInputValue}`)
}

이건 아주 자연스러운 React 방식이야.
searchInputValue는 상태로 관리되고 있고,
navigate()는 react-router-dom의 훅이니까 페이지 전환에 딱 맞음.

추가 팁

혹시 사용자가 엔터를 눌러도 이동되게 하고 싶다면:

<input
  placeholder="도시 이름을 영어로 입력해보세요!"
  onChange={inputChange}
  onKeyDown={(e) => {
    if (e.key === 'Enter') buttonChange()
  }}
/>

 

 

그런데 링크를 다니까 문제점...

하이퍼링크 처럼 아이콘의 색이 약간 바뀌었는데, 이걸 좀 고칠 수 있는 법은?

더보기

<Link>는 기본적으로 브라우저에서 하이퍼링크처럼 동작해서 파란색 텍스트 + 밑줄 스타일이 적용될 수 있다.

특히 <a> 태그로 렌더링되기 때문에 그렇다

아이콘에 그런 스타일이 적용되면 어색하니까, 스타일을 직접 없애주는 게 좋다.


 해결법: Link에 스타일 초기화 주기

예를 들어:

import { Link } from 'react-router-dom';
import { Search } from 'lucide-react';

function MyComponent() {
  return (
    <Link to="/detail" style={{ textDecoration: 'none', color: 'inherit' }}>
      <Search className="cursor-pointer" />
    </Link>
  );
}

 

💡 textDecoration: 'none' → 밑줄 제거
💡 color: 'inherit' → 부모 텍스트 색상 그대로 사용 (아이콘에도 영향 있음)


Tailwind CSS 쓸 경우

만약 Tailwind CSS를 쓰고 있다면 이렇게 쓸 수 있음:

<Link to="/detail" className="no-underline text-inherit">
  <Search className="cursor-pointer" />
</Link>

만약 아이콘 색도 바뀌었다면?

<Link> 안의 아이콘이 파랗게 되었다면, 아마 부모 스타일 영향을 받는 것.
이럴 땐 아이콘에 color 스타일을 직접 지정해줘도 됌

<Search style={{ color: 'black' }} />

혹은 Tailwind에서:

<Search className="text-black" />

 

그러면 이렇게 검색 창도 만들어졌다.

 

 


다음 게시글에선,

1. 검색 창에서 특정 도시를 검색 한 뒤 버튼을 누르면 해당 값으로 api를 호출하고 -> 디테일을 표시해주는 작업을

2. 로딩 창을 구현

3. 추천 옷, 노래 컴포넌트 만들기

4. 한국어 지원으로 변경하기 

동기분의 소개로, 곧 한번 해봐야지 했던 아이콘 사용!

아주 단순하고 쉽다 ! 자주 활용해야지 :)


 

React Icons

 

react-icons.github.io

리액트 아이콘 라이브러리

 

1. 설치

npm install react-icons

 

 

 

2. 사이트에서 원하는 아이콘을 선택 후 (커스터마이징도 쉽게 가능)

 

3. 사용할 컴포넌트 파일에서 import 해준다.

import { FaHeart } from "react-icons/fa";

 

4. 그 뒤, 컴포넌트 처럼 사용해주면 됌.

import { Faheart } from 'react-icons/fa';

function App() {
  return <h1>Let's go for a <Faheart />?</h1>;
}

 


* 공부한 부분 

예를 들어 Search에 관련되어 돋보기 아이콘을 사용해서, 그 아이콘을 버튼 처럼 활용하고 싶다면, 두가지 방법이 있는데 

 

1. 리액트 라우터 링크로 연결

2. onclick으로

 

자세한 설명은 다음과 같다.

더보기

예시 1:  onClick 달기

import { Search } from 'lucide-react'; // 예: lucide-react 아이콘 라이브러리

function MyComponent() {
  const handleClick = () => {
    console.log('아이콘 클릭됨!');
  };

  return <Search onClick={handleClick} />;
}

이렇게 하면 아이콘 누르면 handleClick 실행.


예시 2: Link와 함께 사용하기 (react-router-dom)

import { Search } from 'lucide-react';
import { Link } from 'react-router-dom';

function MyComponent() {
  return (
    <Link to="/detail">
      <Search className="cursor-pointer" />
    </Link>
  );
}

이 경우 Search 아이콘을 클릭하면 /detail로 이동해요.


 예시 3: onClick 안 먹힐 수도 있는 경우

간혹 어떤 아이콘 라이브러리는 SVG로만 구성되어 있어서 onClick이 바로 안 먹힐 수도 있다.
그럴 땐 div, button, 또는 span으로 감싸주면 된다.

function MyComponent() {
  const handleClick = () => {
    console.log('이동~');
  };

  return (
    <div onClick={handleClick} style={{ cursor: 'pointer' }}>
      <Search />
    </div>
  );
}

또는 라우터처럼 쓸 땐 이렇게도 가능하다

import { useNavigate } from 'react-router-dom';

function MyComponent() {
  const navigate = useNavigate();

  return (
    <div onClick={() => navigate('/detail')} style={{ cursor: 'pointer' }}>
      <Search />
    </div>
  );
}

🔑 정리

  • 온클릭 안 될 경우 부모 요소에 onClick 걸고 스타일로 cursor: pointer 넣어주기
  • 라우터 이동 시 <Link> 또는 useNavigate() 사용 가능

 

하나 둘 배워가는 재미가 있어..

 

 

리액트 공부하기 - toastify 라이브러리 초보 설명

조교님이나 동기분들하고 대화하다보면 좋은 꿀 정보를 많이 얻는다 !그 중 하나 toastify.기존 alert 대신에 사용해볼 수 있어서 흥미로워 보였다 ! 라이브러리라 사용도 간편할 것 같았다 🐰🤍 re

creamymood.tistory.com


 

이렇게 뜨는 alert창을 toastify로 바꿔보자 둑흔

 

짜잔~


toastify 컴포넌트를 만든 뒤 -> alert 자리에서 import 해와서 사용한다.

또는 간단한 제공 함수를 사용한다.

 

 

우선 챗지피티 알려준 자세한 설명은 다음과 같다.

더보기

1. 우선 라이브러리 설치

npm install react-toastify

 

2. toastContainer 전역에서 사용하기 위해 app.js 또는 Root 컴포넌트에 넣어주기

import { ToastContainer } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';

function App() {
  return (
    <>
      {/* 다른 컴포넌트들 */}
      <ToastContainer />
    </>
  );
}

 

3. toast 함수를 사용할 유틸 파일 만들기 (선택)
예: toastUtil.js

import { toast } from 'react-toastify';

export const notifySuccess = (message) => toast.success(message);
export const notifyError = (message) => toast.error(message);
export const notifyInfo = (message) => toast.info(message);

 

4. 기존 alert("문구") → toast 함수로 교체

import { notifySuccess } from './toastUtil';

// 예시:
notifySuccess("성공적으로 저장되었습니다!");

helper 함수 사용

기존

const handleClick = () => {
  alert("저장되었습니다!");
}

 

변경 후

import { toast } from 'react-toastify';

const handleClick = () => {
  toast.success("저장되었습니다!");
}

나는 간단히, helper 함수 사용해봤다.


추가 ! 조금 꾸며보기..

 

helper 함수에도 이렇게 넣을 수 있으니까, 간단히 이런 방식으로 해보기

toast.success("저장 완료!", {
  position: "bottom-right",
  autoClose: 3000,
});

 

그런데 필요한 부분마다, 이렇게 css나 필요한 것을 적용하긴 귀찮을 것 같으니, 유틸 파일을 만들어두는 편이 훨씬 낫겠다.

 

 

색상이나 스타일 지정 하는 법↓

더보기

리액트에서 react-toastify를 사용할 때 색상이나 스타일을 커스텀하는 방법은 여러 가지


1. ToastContainer에서 theme, position, autoClose 설정하기

import { ToastContainer } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';

function App() {
  return (
    <>
      {/* 앱 컴포넌트들 */}
      <ToastContainer
        position="top-right"
        autoClose={3000}
        hideProgressBar={false}
        newestOnTop
        closeOnClick
        rtl={false}
        pauseOnFocusLoss
        draggable
        pauseOnHover
        theme="dark" // light | dark | colored
      />
    </>
  );
}

 

2. 개별 Toast에 스타일 커스텀하기

toast() 함수에 style 객체 전달:

import { toast } from 'react-toastify';

toast('Custom styled toast!', {
  style: {
    background: '#333',
    color: '#fff',
    fontWeight: 'bold',
  },
});

 

3. className을 사용해서 커스텀 CSS 적용

toast('Hello!', {
  className: 'my-toast',
  bodyClassName: 'my-toast-body',
  progressClassName: 'my-progress-bar',
});
/* 예시: styles.css */
.my-toast {
  background-color: #222 !important;
  color: #ffcc00 !important;
  font-size: 16px;
}

.my-toast-body {
  font-weight: bold;
}

.my-progress-bar {
  background: linear-gradient(to right, #f00, #0f0);
}

※ !important를 붙이지 않으면 기본 스타일에 덮어씌워지지 않는 경우도 있다.

4. 아이콘 제거하거나 교체하기

toast('No icon toast', {
  icon: false,
});
toast('Custom icon', {
  icon: '🚀',
});

 

 5. toast.success, toast.error 등 별도 색상 변경

기본 colored 테마일 때 색상 커스텀은 제한적이므로, className + CSS 방식이 가장 유연하다

toast.success('Success message', {
  className: 'my-success-toast',
});
.my-success-toast {
  background-color: #2e8b57;
  color: white;
}

 

팁: Tailwind CSS를 쓰는 경우

toast('Tailwind styled toast', {
  className: 'bg-black text-white text-sm',
});

 

 

 

짜잔 ! ~

 


 

 

조교님이나 동기분들하고 대화하다보면 좋은 꿀 정보를 많이 얻는다 !

그 중 하나 toastify.

기존 alert 대신에 사용해볼 수 있어서 흥미로워 보였다 ! 라이브러리라 사용도 간편할 것 같았다 🐰🤍


 

 

 react-toastify란?

사용자에게 빠르고 가볍게 피드백(알림)을 줄 수 있는 Toast UI 라이브러리


"Toast"란?

웹/앱에서 화면 한쪽에 짧게 뜨는 알림 메시지

  • 로그인 성공 → "로그인에 성공했습니다!"
  • 장바구니 추가 → "상품이 장바구니에 담겼어요."

공식 문서에서 안내해주는 설치 방법과 간단한 사용 예시

Installation

$ npm install --save react-toastify
$ yarn add react-toastify
  import React from 'react';

  import { ToastContainer, toast } from 'react-toastify';
  
  function App(){
    const notify = () => toast("Wow so easy!");

    return (
      <div>
        <button onClick={notify}>Notify!</button>
        <ToastContainer />
      </div>
    );
  }

 

 

 

React-toastify | React-Toastify

Financial Contributors on Open Collective

fkhadra.github.io

해당 사이트는, 사용방법 등 다양하게 안내되어 있다.

 

사이트에서 이런 식으로 쉽게 예시를 직접 볼 수 있고, 커스터마이징 할 수 있다.

 

 


사용방법

1) 커스텀 컴포넌트 없이,  당장 실행 시켜볼 수 있는 초간단 코드 

(공식으로 제공하는 간단한 helper 함수). 

 

toast.success, toast.error, toast.info, toast.warn 등은
toast() 함수의 shortcut 버전으로 초 간단히~~ 컨테이너만 넣어주고, 사용 원하는 컴포넌트에서 바로 이렇게 사용하면

toast("일반 메시지"); // 기본 Toast
toast.success("성공 메시지");
toast.error("에러 메시지");
toast.info("정보 메시지");
toast.warn("경고 메시지");

 

원하는 위치나 지속시간도 지정 가능하다.

toast.success("저장 완료!", {
  position: "bottom-right",
  autoClose: 3000,
});

 


 

 

2) 유틸 파일을 만들어서, 원하는 대로 사용

: toastUtil.js 이런 식으로 만들어서

import { toast } from 'react-toastify';

export const notifySuccess = (message) => toast.success(message);
export const notifyError = (message) => toast.error(message);
export const notifyInfo = (message) => toast.info(message);

 

. 기존 alert("문구") → toast 함수로 교체

import { notifySuccess } from './toastUtil';

// 예시:
notifySuccess("성공적으로 저장되었습니다!");

주의 !

1. <ToastContainer />는 반드시 넣어야 한다.


toast() 함수는 단순히 "띄워줘!" 하고 명령만 내릴 뿐이고,
<ToastContainer />가 실제로 그걸 브라우저에 표시하는 역할

 

보통 이런 식으로 넣는다.

function App() {
  return (
    <>
      <MyComponent />
      <ToastContainer />
    </>
  );
}
  • 보통은 앱의 루트 컴포넌트에 한 번만 넣음
  • 여러 개 넣으면 알림이 중복될 수 있다

 

 2. CSS import도 절대 기억하기

 

react-toastify는 기본 스타일이 있어야 알림이 제대로 보인다.

import 'react-toastify/dist/ReactToastify.css';

Toastify 추가 주의사항 & 유용한 팁

더보기

1. 중복 알림 방지하려면 toast.isActive() 사용

  • 같은 메시지가 계속 떠서 사용자에게 불편함을 줄 수 있다
  • 이럴 땐 중복 방지를 위해 ID를 설정하거나, toast.isActive()를 사용 하기
const toastId = 'saving';

if (!toast.isActive(toastId)) {
  toast.success('저장되었습니다!', { toastId });
}

 

 

2.  자동 닫힘 시간 설정 (autoClose)

toast('3초 후 닫힘!', {
  autoClose: 3000, // 3초
});
  • 기본값은 5초 (5000ms)
  • false로 하면 수동으로만 닫을 수 있음

3. 위치 조절 (position)

<ToastContainer position="top-center" />
  • 기본값: top-right
  • 다른 값들:
    top-left, top-center, bottom-left, bottom-right, bottom-center

4.  스타일 커스터마이징

toast.success('완료!', {
  style: {
    backgroundColor: '#333',
    color: '#fff',
  },
});

또는 ToastContainer에 theme을 지정해도 됌:

<ToastContainer theme="dark" />

 

 

5.  Promise와 함께 쓰기 (toast.promise)

  • API 호출 같은 비동기 처리에서 유용
toast.promise(fetch('/save'), {
  pending: '저장 중...',
  success: '저장 완료!',
  error: '저장 실패 😢',
});

 

6. 한 번에 모든 Toast 지우기

toast.dismiss(); // 모든 토스트 닫기

또는 특정 ID만 닫기:

toast.dismiss(toastId);

 

 


리액트 toastify 공식 문서 

 

react-toastify

React notification made easy. Latest version: 11.0.5, last published: 3 months ago. Start using react-toastify in your project by running `npm i react-toastify`. There are 2977 other projects in the npm registry using react-toastify.

www.npmjs.com

 

공부는 끝이없다 . .  

이제 조금 내공이 생겨(?) 코드를 직접 작성 해보려고 하는데.. map 뒤부터 헷갈리기 시작 😭..

진짜 자바스크립트 지식이 부족해서 그런가.. 여기저기 자꾸 구멍이 뚫리는 기분이지만 !

이렇게 된거 다시 깊게 공부하자고 생각하고 공부~

정신 차료~

 


일단 배열이 있으면 해당 배열을 map을 돌릴 때, 

배열.map() 이런식의 문법은 당연히 알고 있었는데, () 내부가 헷갈렸다.

 

그래서 몇가지 공부를 했고,

당연하다고 생각했는데, 다시 머릿속에 집어넣은 개념들은 아래와 같다. 결론 먼저 정리 하고 가기!


(() =>{}) 이것도 있고..

(() =>()) 이것도 있고..

 

각각 차이를 알아보니, 우선 이 둘의 차이는 return의 차이 였다. 


((example)=>()) 이것도 있고

(example =>()) 이것도 있고..

 

이 둘의 차이는 매개변수를 확실하게 해줄지 아닐지의 차이고.

매개변수가 하나라면 () 안에쓰든, 그냥 쓰든 무방 한 것 같다. 🤔

 


 

❸ 리턴 값에 새로운 배열이 들어가는 것!

map을 돌려서 새로 보여줄 걸 적는 곳!!


1. map()이란?

배열의 모든 요소에 대해 어떤 작업을 수행하고, 그 결과로 새로운 배열을 반환하는 함수.

 

const numbers = [1, 2, 3];
const doubled = numbers.map(num => num * 2);
console.log(doubled); // [2, 4, 6]

2. 기본 문법

array.map((element, index, array) => {
  // 리턴값이 새로운 배열에 들어감
});
  • element: 현재 요소
  • index: 현재 요소의 인덱스
  • array: 원본 배열

🧚‍♀️3. ( ) vs { } 차이  :: 바로 RETURN !

이게 정말 중요한 포인트다

✓ ()=>{} 중괄호 사용 시

array.map((item) => {
  return <div>{item}</div>;
});

중괄호를 쓸 경우, return을 꼭 써줘야 함

✓ ()=>() 소괄호 사용 시

array.map((item) => (
  <div>{item}</div>
));

소괄호를 쓰면 암묵적(자동)으로 return이 된다!

즉, 아래 두 코드는 같은 의미

// 방법 1: 중괄호 + return
items.map(item => {
  return <div>{item}</div>;
});

// 방법 2: 소괄호 (자동 return)
items.map(item => (
  <div>{item}</div>
));

React에서는 JSX를 리턴해야 할 때가 많기 때문에, 소괄호 방식이 더 깔끔하고 자주 쓰인다


4. 리액트 예제

const names = ['Jane', 'Tom', 'Sally'];

function App() {
  return (
    <div>
      {names.map(name => (
        <p key={name}>Hello, {name}!</p>
      ))}
    </div>
  );
}
  • map()으로 각각의 이름을 <p>로 렌더링
  • key는 리액트가 각 요소를 추적하기 위해 필요해 (반복문 쓸 때 필수!)

둘의 형태 비교

1. (example => ( ... ))   // 괄호 없이 변수 선언
2. ((example) => ( ... )) // 괄호 안에 변수 넣음

차이점 설명

1. (example => (...))

  • 매개변수가 하나일 때는 괄호 없이 example => ... 이렇게 써도 돼.
  • 간결해서 가장 많이 쓰이는 형태야.

 

items.map(item => <div>{item}</div>);

 

 

2. ((example) => (...))

  • 매개변수가 2개 이상이거나,
  • 예외 상황 (구조분해, 기본값 등) 을 쓸 땐 괄호가 필수
  • 또는 그냥 더 명확하게 보이도록 일부러 괄호를 쓰기도 함

 

items.map((item, index) => <div key={index}>{item}</div>); // 2개니까 괄호 O
items.map(({ name }) => <div>{name}</div>); // 구조분해니까 괄호 O
items.map((item = 'default') => <div>{item}</div>); // 기본값 설정이니까 괄호 O

 

코드를 작성하는데, 예를 들어

const fetchWeather = async (lat, lon) => {
        const key = import.meta.env.VITE_WEATHER_KEY
        const url = `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${key}&lang=kr`

        try{
        const respose =  await fetch(url);
        const data =  await respose.json()
        console.log(data)
        setWeather(data)
    }


    //도시 이름으로, 날씨 호출하기 함수
    const cityWeather = async() => {
        const key = import.meta.env.VITE_WEATHER_KEY
        const url = `https://api.openweathermap.org/data/2.5/weather?q=Tokyok&appid=${key}`

        try{
          const response = await fetch(url)
          const data = await response.json()
          console.log(data)
          setTokyoWeather(data)

        }
  
    }

* 해당 코드는 가독성이 좋게 일부 생략했음*

 

 

fetchWeather에서 특정한 값을 key 상수에 할당 했는데, 

갑자기, 다른 cityWeather 함수에서도 같은 값을 할당해서 사용하려고 불러오거나 적으려고 하니..

이 key를 다시 써도 되는건지, cityKey 이런식으로 다시 할당을 해야 하는지 고민이 되었다.

 

(자바스크립트 기초가 부족하다는 뜻 - 😭)

 

그래도 공부한 짬밥으로, 뭔가 함수 안에서 스코프?가 있다는 걸 어느정도 짐작했어서, 저렇게 다른 함수에서 같은 상수명을 써도 될 것 같았고 공부해봤다.

정답 :

JS에서 const는 **블록 스코프(block scope)**를 가지기 때문에, 함수 안에 선언된 변수는 그 함수 안에서만 유효하다.

그래서 fetchWeather() 안에서 선언한 const key는 fetchWeather() 밖에서는 쓸 수 없다.
cityWeather()는 다른 함수니까, 거기서 다시 선언해줘야 한다.
1. 블록 스코프란?
{} 중괄호로 감싸진 코드 블록 내부에서만 유효한 변수 범위를 말한다.

* JS에서 let과 const는 블록 스코프를 갖고, var은 함수 스코프를 갖는다.
{
  let a = 10;
  const b = 20;
}
console.log(a); // ❌ 에러! 블록 밖에서는 접근 불가​

따라서 다른 함수에서 동일한 변수명을 사용해도 상관이 없다!

2. 이러한 이유로, 변수나 상수는 리액트에서 렌더링이 될 때마다, 변수가 새로 선언되기 때문에.
   즉, 변수를 통해 값을 저장하거나 유지하는 데 적합하지 않다.

이런 변수들은 계산용 임시값, map() 같은 JSX 변환용으로만 사용하는 게 좋다.

 

 

* 이 경우도 참고하자. 

리액트 함수 컴포넌트는, 컴포넌트 자체가 함수이기 때문에 내부가 블록 스코프다.

따라서

function MyComponent() {
  const text = "hello";

  function innerFunc() {
    console.log(text); // ✅ 접근 가능
  }

  innerFunc();
}

 

이렇게 맨 윗 상단에 상수 값을 할당해주면 이건 이제 안에 있는 다른 함수에서 접근이 가능한 것.

 


 

리액트에선, 항상 컴포넌트 맨 윗단에 useState로써 상태를 사용할 때 이 값은 컴포넌트 내에서 언제든 불러서 썼었네.. ? 하면서, 아

상태는 다르구나 라고 짐작했고, 정확한 내용은 아래와 같았다.

리액트의 컴포넌트는, 그냥 "렌더링 함수"다.
따라서 컴포넌트는 함수 자체가 블록 스코프다.

버튼을 누르든, 상태가 바뀌든, 이벤트가 생기든 아무튼 이러한 일이 벌어질 때 마다,
컴포넌트는 렌더링 되기 때문에, 일반 변수나 상수에 값을 저장하게 되면 그 값이 기억할 수 없다.


"값을 유지하고 저장하기" 위해서는 React가 리렌더링 시에도 기억할 수 있게 해야 한다.

이 때 사용하는 것이 useState인데, useState는 값을 기억하고 저장할 수 있게 해준다.

useState 는 단순한 함수가 아니라, React가 따로 기억해두는 공간을 만든다.
그리고 이 공간은 함수가 다시 실행되어도
값이 날아가지 않는다 !! 

const [count, setCount] = useState(0);

이 코드를 보면 useState(0)는 처음 실행될 때
React가 count라는 이름으로 내부 저장소에 0을 저장해준다.

그 이후에는:

  • 상태가 바뀔 때마다 setCount를 통해 값을 업데이트한다.

일반 변수 (let, const) 컴포넌트 함수가 실행될 때마다 다시 초기화됨
useState React가 값을 컴포넌트 외부에 따로 저장해주고, 리렌더링 후에도 유지됨
이유 React는 함수 컴포넌트를 다시 실행하기 때문에, 상태 유지하려면 별도 저장소가 필요함

 

👩🏻‍💻공부하는 새로운 분야의 새롭게 접하는 용어나 단어가 느껴지기만 하면, 거부감이 느껴진다.

 

낯선 분야에 대해 조금은 쉽게 적응하기 위해서는

어려운 용어에 대하여 먼저 정리를 하면 보다 효율적으로 공부가 가능하다는 First Word 법칙이다.

 

낯설고 이해하기 어려운 그러한 단어들을 나만의 단어로 내가 이해할 수 있게 정리한다.

 

비유적인 표현으로 먼저 공부하고 또 나만의 언어로 정리해보고 이해해보고

정확한 정의나 개념으로는 추후에 익숙해져도 된다!


 

오늘 새로운 AWS 강의를 들으며 강사님께서 알려주신 공부법인데

이미 나는 코딩 공부에 적용하고 있구나. 잘하고 있구나를 깨달았다. 또 새로운 과목도 화이팅~

'Mental health care' 카테고리의 다른 글

아토믹 해빗  (0) 2025.02.20
메타인지. 아무도 완벽하지 않다.  (0) 2025.02.19
뇌 가소성. 그리고 나의 다짐.  (0) 2025.02.18

API로 데이터 받아올 때, 종종 들었던 엔드포인트에 대해 공부하고 넘어가보자

 


API 엔드 포인트란?

: API 엔드포인트(API endpoint)"는, API를 통해 접근할 수 있는 URL 주소

 

 

특정 웹사이트가 있고, 그 웹사이트에서 날씨 정보를 가져오는 기능이 있다면, 이런 URL이 있을 수 있다.

https://api.weather.com/current?city=Seoul

이 주소가 바로 엔드포인트.

 이 URL로 요청을 보내면, 서버는 "서울의 현재 날씨" 정보를 응답으로 준다.

  • API: 애플리케이션끼리 데이터를 주고받기 위한 규칙.
  • 엔드포인트: API의 특정 기능에 접근하는 URL.

 

예제 🍏

 

날씨 정보를 제공하는 API가 있다고 할 때:

https://api.weather.com

이게 기본 URL (즉, 기본 API 주소)이라면,

 

엔드포인트는 이렇다. 

현재 날씨:

https://api.weather.com/weather/current

주간 예보:

https://api.weather.com/weather/weekly

특정 도시 날씨:

https://api.weather.com/weather/current?city=Seoul

 

 

개인 프로젝트 - 날씨 앱 (1) 현재 위치 받아오기

날씨앱 메인페이지에서 구현 할 내용이, 내가 있는 위치의 날씨 정보 이므로, 현재 위치를 우선 알아야 한다.그 과정에 필요한 내용.날씨 앱 말고도 현재 위치로써 활용할 수 있을 내용이 많을

creamymood.tistory.com

 

앞 게시글에서 이어집니다.


2. 현재 위치 날씨 호출 하기

 

현재 위치를 받아왔으니, 해당 정보를 기반으로 날씨도 호출해보자.

큰 틀은 다음과 같다.

 

1. Home.jsx에서 현재 날씨를 호출한다. 

2. 받아온 정보에서 필요한 내용들로 아래 내용 처럼 간단한 필요한 구성을 한다.


 

같이 공부하시는 동기님이 알려주신 날씨 API 사이트


❶ 우선 회원가입을 한 뒤, key 값을 받고, .env 변수에 담아, 컴포넌트에선 import 해둔다.

 

const key = import.meta.env.VITE_WEATHER_KEY

 

 

❷ 현재 날씨를 호출 하는 법은 간단하다.

https://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&appid={API key}

 

날씨 호출 해오는 코드의 lat은 위도 / lon은 경도다.

 

* 참고로 다국어 지원도 한다. 엔드포인트는 다음을 참고하자.

더보기

한국이면 lang에 kr 넣으면 됨~

&lang=kr

 

이렇게 적으면, 

이렇게 뜨는데, 도시는.. 변경이 안되나보다.

이 부분 동기님이 언급해주셨는데, 한번 고민해봐야겠다.

 

컴포넌트 분리 전에,

우선 메인 페이지인, home.jsx에서 위치를 불러 왔었다.

 //현재 위치 받아오기 함수
    useEffect(()=>{
        navigator.geolocation.getCurrentPosition(
        
            function success(position){
                setLat(position.coords.latitude)
                setLon(position.coords.longitude)},
            function error(error){console.log(error)}
            )
       
    },[])

해당 코드 처럼 latitude와 longtitude를 각각 상태로써 저장해줬다.

 

이 값으로

const [lat, setLat] = useState(null)
    const [lon, setLon] = useState(null)
    const [weather, setWeather] = useState(null)
    // const key = import.meta.env.VITE_WEATHER_KEY

    const fetchWeather = async (lat, lon) => {
        const key = import.meta.env.VITE_WEATHER_KEY
        const url = `https://api.openweathermap.org/data/2.5/weather?lat=${lat}&lon=${lon}&appid=${key}`

        try{
        const respose =  await fetch(url);
        const data =  await respose.json()
        console.log(data)
        setWeather(data)

        }catch (error){
            console.error('날씨 데이터를 불러오지 못했습니다:', error);
        }
    }

날씨를 호출하는 함수를 만든다. 

데이터를 받아온 뒤, 그것 역시 날씨 데이터로 저장해준다.

 

그 뒤, fetchWeather 함수를 실행하는데, lat과 lon 값이 있을 때! fetchWeather을 실행하도록,

아래처럼 useEffect안에 넣어준다.

useEffect(() => {
        if (lat && lon) {
            fetchWeather(lat, lon);

        }
    }, [lat, lon]);

 

그리고 콘솔을 확인해보면,

이렇게 잘 뜨는 것을 확인 할 수 있다.

 

공식 문서에서 API 응답에 대한 부분을 설명해주고 있는데, 아래 데이터 정보를 확인 후 

필요한 데이터를 추출하여 화면에 렌더링 해주면 된다.

더보기
                          
{
   "coord": {
      "lon": 7.367,
      "lat": 45.133
   },
   "weather": [
      {
         "id": 501,
         "main": "Rain",
         "description": "moderate rain",
         "icon": "10d"
      }
   ],
   "base": "stations",
   "main": {
      "temp": 284.2,
      "feels_like": 282.93,
      "temp_min": 283.06,
      "temp_max": 286.82,
      "pressure": 1021,
      "humidity": 60,
      "sea_level": 1021,
      "grnd_level": 910
   },
   "visibility": 10000,
   "wind": {
      "speed": 4.09,
      "deg": 121,
      "gust": 3.47
   },
   "rain": {
      "1h": 2.73
   },
   "clouds": {
      "all": 83
   },
   "dt": 1726660758,
   "sys": {
      "type": 1,
      "id": 6736,
      "country": "IT",
      "sunrise": 1726636384,
      "sunset": 1726680975
   },
   "timezone": 7200,
   "id": 3165523,
   "name": "Province of Turin",
   "cod": 200
}

 

설명:

  • coord
    • coord.lon위치의 경도
    • coord.lat위치의 위도
  • weather(자세한 정보 날씨 상황 코드 )
    • weather.id날씨 상태 ID
    • weather.main날씨 매개변수 그룹(비, 눈, 구름 ​​등)
    • weather.description그룹 내 날씨 상황입니다. 자세한 내용은 여기에서 확인하세요. 원하는 언어로 결과를 확인하실 수 있습니다. 자세히 알아보기
    • weather.icon날씨 아이콘 ID
  • base내부 매개변수
  • main
    • main.temp온도. 기본 단위: 켈빈, 미터법: 섭씨, 영국식: 화씨
    • main.feels_like온도. 이 온도 매개변수는 사람의 날씨 인식을 반영합니다. 단위 기본값: 켈빈, 미터법: 섭씨, 영국식: 화씨
    • main.pressure해수면의 대기압, hPa
    • main.humidity습도, %
    • main.temp_min현재 최저 기온입니다. 현재 관측된 최저 기온입니다(대도시 및 도시 지역). 자세한 내용은 여기에서 확인하세요. 기본 단위: 켈빈, 미터법: 섭씨, 영국식: 화씨
    • main.temp_max현재 최고 기온입니다. 현재 관측된 최고 기온입니다(대도시 및 도시 지역). 자세한 내용은 여기에서 확인하세요. 기본 단위: 켈빈, 미터법: 섭씨, 영국식: 화씨
    • main.sea_level해수면의 대기압, hPa
    • main.grnd_level지상의 대기압, hPa
  • visibility시정, 미터. 시정의 최대값은 10km입니다.
  • wind
    • wind.speed풍속. 기본 단위: 미터/초, 미터법: 미터/초, 영국식 단위: 마일/시
    • wind.deg풍향, 도(기상학적)
    • wind.gust돌풍. 단위 기본값: 미터/초, 미터법: 미터/초, 영국식: 마일/시
  • clouds
    • clouds.all흐림, %
  • rain
    • 1h(사용 가능한 경우) 강수량(mm/h). 이 매개변수의 측정 단위는 mm/h만 사용 가능합니다.
  • snow
    • 1h(사용 가능한 경우) 강수량(mm/h). 이 매개변수의 측정 단위는 mm/h만 사용 가능합니다.
  • dt데이터 계산 시간, 유닉스, UTC
  • sys
    • sys.type내부 매개변수
    • sys.id내부 매개변수
    • sys.message내부 매개변수
    • sys.country국가 코드(GB, JP 등)
    • sys.sunrise일출 시간, 유닉스, UTC
    • sys.sunset일몰 시간, 유닉스, UTC
  • timezoneUTC에서 초 단위 변화
  • id 도시 ID. 내장된 지오코더 기능은 더 이상 지원되지 않습니다. 자세한 내용은 여기를 참조하세요.
  • name 도시 이름입니다. 기본 제공 지오코더 기능은 더 이상 지원되지 않습니다. 자세한 내용은 여기를 참조하세요.
  • cod내부 매개변수

 

❸ 그리고 필요한 데이터로 이제 return 부분을 채워준다.

 

 

주의 !

1) weather는 비동기로 받아오는 데이터기 때문에

(처음 렌더링 시점에 weather 값이 아직 null. 즉, weather.name이나 weather.weather[0]에 접근하려 할 때 에러가 발생할 수 있다.)

따라서, 조건부 렌더링으로써 weather가 존재하고 weather.weather가 배열인지 확인한 다음에 렌더링하도록 !

 

2) 받아온 데이터에 ICON도 있는데, 이걸 실제 이미지로 변경 하고 싶을 땐, 아래를 참고해보자

더보기

 날씨 아이콘을 텍스트로 보여주는 게 아니라 진짜 이미지로 보여주고 싶을 때는, OpenWeatherMap에서 제공하는 아이콘 URL 포맷을 사용하면 된다.


 1. 아이콘 코드란?

weather.weather[0].icon 이 부분에는 "01d", "03n" 같은 코드가 들어 있어.
이 코드는 날씨 아이콘을 식별하는 문자열이야.

weather.weather[0].icon // "01d"

 

 2. 이미지로 변환하는 방법

아이콘 이미지는 다음 형식의 URL을 쓰면 돼:

http://openweathermap.org/img/wn/{icon}@2x.png

여기서 {icon} 자리에 코드 (01d 등)가 들어가.

 

예:

<img src={`http://openweathermap.org/img/wn/${weather.weather[0].icon}@2x.png`} alt="weather icon" />

3. 현재 위치 날씨 칸을 누르면 디테일 페이지로 이동하기

 

우선 이렇게 현재 위치를 기반으로 날씨까지 받아와서, 해당 정보로 화면을 꾸려주었다.

 

(2) 현재 위치 칸을 누르면, 디테일로 가기 위한 구성을 하기 위해 router를 설치해주었고 다음과 같이 페이지 설정을 해주었다.

 

css 스타일링을 하기 전에, 우선 div 칸을 누르면 디테일로 이동하게끔 구현 하고 싶은데

 

내 머릿속에서 생각한 방법은, LINK를 div 안에 넣을 수 있나 ?

 

<div> 자체를 클릭해서 이동하게 하고 싶다면, <Link>를 <div>처럼 꾸미거나, <div> 대신 <Link>를 쓰는 게 더 좋다.

 

 

 1) div 안에 Link 넣는 건 괜찮음:

<div>
  <Link to="/home">Home</Link>
</div>

2 ) div를 클릭해서 이동하게 하고 싶을 때 이렇게 하면 접근성/SEO에 안 좋음:

<div onClick={() => navigate('/home')}>Home</div>

 

이유?  ↓

더보기

"접근성(Accessibility)이나 SEO(Search Engine Optimization)에 안 좋다"는 건 웹사이트를 사용하는 사용자나 검색 엔진에게 불리하게 작용할 수 있다는 뜻

 예시 코드 (접근성/SEO에 안 좋음)

<div onClick={() => navigate('/home')}>
  홈으로 가기
</div>

왜 이게 안 좋을까?

1. 접근성 문제 (Accessibility)

  • 스크린 리더(시각장애인용 보조 도구) 는 <a>, <button> 같은 HTML 기본 태그를 기준으로 동작한다.
  • <div>는 기본적으로 클릭 가능한 요소로 인식되지 않아, 키보드로 접근이 불가능하거나, 어떤 동작이 있는지 인식하기 어렵다.
  • 키보드로만 웹을 사용하는 사람은 이걸 "클릭할 수 있는 버튼"이나 "링크"라고 느끼지 못한다.

2. SEO 문제 (Search Engine Optimization)

  • 검색 엔진은 <a href="..."> 같은 명확한 링크 구조를 통해 페이지 간 관계를 이해한다.
  • <div>에 onClick을 써서 페이지 이동하게 하면 검색 엔진이 링크로 인식하지 못해서 페이지 연결 정보를 놓쳐, SEO 점수에 불리하게 작용할 수 있다.

 

올바른 방법

방법 1: <Link>를 사용

import { Link } from 'react-router-dom';

<Link to="/home" className="my-div-style">
  홈으로 가기
</Link>

CSS로 스타일을 줘서 <div>처럼 보이게 만들 수 있음.

 

방법 2: <button> + navigate (버튼 역할일 때)

import { useNavigate } from 'react-router-dom';

function MyComponent() {
  const navigate = useNavigate();

  return (
    <button onClick={() => navigate('/home')}>
      홈으로 가기
    </button>
  );
}

 

이럴 땐 <Link> 자체를 스타일링:

<Link to="/home" style={{ display: 'block', padding: '1rem', background: '#eee' }}>
  Home
</Link>

 

 

 

 

그럼 우선 이렇게 되었고, 클릭 시 detail로 이동까지 된다.


추가 +

UI 목표에서 온도를 보여줘야 하는데, 기본적으로 API 호출에서 받아오는 데이터 값은 kelvin이므로 (1) 변환을 해주던가, (2) 처음부터 섭씨로 API를 호출 해와야 한다.

다행히, OpenWeather 사이트에서 섭씨로써 호출 해오는 엔드포인트를 제공한다.

https://api.openweathermap.org/data/2.5/weather?lat=57&lon=-2.15&appid={API key}&units=metric

이렇게 호출 하면 됌! 전체적으로 코드를 수정해줄 필요가 있다.


다음 게시글에선 도시 기반으로 날씨를 보여주는 (7)~(9) 기능을 구현 해보겠다. 🤍💘


참고한 블로그 :

 

 

[React] API로 날씨 앱 만들기 1(OpenWeather API 사용)

오늘은 API를 사용하여 날씨 앱을 만들어 보자. 최종 결과물은 아래와 비슷한 구성이 될 것이다. https://velog.io/@gyultang/React%EB%A1%9C-%EB%82%A0%EC%94%A8%EC%95%B1-%EB%A7%8C%EB%93%A4%EA%B8%B0OpenWeather-API React로 날씨

conquer-it.tistory.com

 

 


1. INSERT

  • 1. CRUD란?
  • 2. 테이블 구성 요소
  • 3. 테이블 채우기 (데이터 삽입)

2. SELECT

  • 1. 테이블 조회 (전체 조회? 부분 조회?)
  • 2. 정렬 관련 문법 - ORDER BY, LIMIT키워드, 자주 사용되는 함수, DISTINCT 키워드          

3. UPDATE

  • 1. UPDATE 명령어
  • 2. 실수 방지 대비

4. DELETE

 

 


1. INSERT 

1- 1. CRUD란?

CREATE

READ

UPDATE

DELETE

 

insert는 CREATE에 가깝다.

select는 READ에 가깝다.

update와 delete는 update, delete다!

1-2. 테이블의 구성 요소는 다음과 같다.

 

1-3 테이블에 데이터 삽입

이러한 테이블에 데이터 삽입 하려면, 

먼저 CREATE TABLE 명령어로 테이블 생성 ->

INSERT INTO 명령어로 데이터를 삽입할 수 있다.

 

** INSERT INTO는 문법에 주의 해야 하는데

 ❶ INSERT INTO 뒤에 컬럼 명을 작성 하고 VALUES 뒤에는 실제 삽입한 데이터를 넣으면 된다.

 ❷ 컬럼 이름과 컬럼 값의 순서 준수

 ❸ created_at은 타임스탬프가 디폴트로 적용되어 있어서, 레코드 삽입할 때 시간이 기록되는 부분.


2. SELECT

READ는 write에 비해 할 일도 많고, 직접 SQL 문을 작성할 일이 많다.

 

2-1. 테이블 조회

 

데이터 조회 명령을 위해서는 SELECT 명령어를 쓴다.

* 별표 표시는 모든 칼럼을 의미

 

특정 조건으로도 조회할 수 있다.

 

** 전체 컬럼 조회는 DBMS가 리소스를 낭비하지 않도록 꼭 필요한 경우에만 전체 조회를 하도록 추천된다.

 

 

2-2 특정 칼럼 조회 방법

위 처럼 작성하면, 아래 부분이 해당 된다.

Select 키워드 다음, 선택하고자 하는 컬럼 명을 쉼표로 구분해서 입력하고  FROM 키워드 뒤에 테이블 명 작성

 

 

 

2-3  특정 로우 조회 방법

 WHERE 키워드 사용하면 특정 로우들을 조회할 수 있다.

 

 예시 1 )

 

아래 처럼 작성하게 되면, 평점 4.5 이상의 모든 로우가 선택 되고 

해당 테이블은 모두 4.5이상이기 때문에, 결과로 모든 로우가 반환 된다.

 

예시 2) 

 

 

아래 처럼 작성하게 되면, 평점 4.5 이상, 4.6 이하의 모든 로우가 선택 되고 

해당 테이블은 결과로 Nomad House가 반환된다.

 

이 외에도,

where와 함께 해당 키워드들을 사용하여, 조회할 수 있다.

 

 

2-4 Select 명령과 정렬관련 문법

 

 

❶ 정렬은 ORDER BY 구문 사용

ORDER BY 뒤에는 기준이 되기 원하는 컬럼 명을 작성한다. 

그리고 그 뒤, 오름 차순으로 정렬하려면 ASC, 내림 차순으로 정렬하려면 DESC를 작성하면 된다.

* 내림차순이란 : 높은 값 -> 낮은 값 정렬 순서

이걸 저 명령어로 쓰면, 아래 사진 처럼 된다.

 

❷ LIMIT 키워드

LIMIT를 사용하여 로우 개수를 제한 하면, "상위 몇등"과 같은 쿼리를 만들 수 있다.

 

 

❸SELECT와 자주 사용되는 함수

 

* 함수 예시

AVG에 숫자값으로 구성되어 있는 컬럼 이름 넣어주고, 결과값의 이름을 as와 같이 적어주면 되는데

select문에 특별한 조건이 걸려있지 않기 때문에, 이 쿼리문은 rating만 조회. 그걸 AVG 함수로 계산하게 되고 그 컬럼의 평균 값을 반환한다.

 

 

❹DISTINCT 키워드

중복되지 않는 고유한 값을 선택하는 조건을 거는 키워드


3. UPDATE

3-1 UPDATE 명령어

테이블 로우 갱신하기 위해서는 update 명령어를 사용하는데, 

- UPDATE 뒤에는 테이블 명

- SET 뒤에는 [변경 하고자 하는 컬럼 명 = 변경 후 값]을 적고 

- 바꾸고자 하는 로우에 해당 조건을 where로 걸어준다.

 

예제1)

해당 쿼리는 id가 1인 로우를 찾아서 해당 로우의 rating을 4.9로 변경

예제 2)

해당 쿼리는 로우 하나의 여러 값을 변경.
이렇게 변한다.

예제3)

이 쿼리문은
아래 처럼 변경

 

업데이트는 실수가 치명적이기 때문에, 아래와 같은 과정이 요구 된다.

 

3-2 실수 방지를 위하여

 

 

먼저 해보고, 데이터가 바뀌어도 괜찮은지 확인

 

❷백업


4. DELETE

4-1 DELETE 명령어

+ Recent posts