본문 바로가기

응용SW 개발 (React)/필기일지

231026 [응용SW개발] - API (TMDB 실습) / React API 활용 (useEffect, useState, grid, Fragments 등)

반응형

[23.10.26] 58일차

 

<<진도>>

[DB 연동 응용SW 개발]ㅋ

- API (TMDB 실습)

- React API 활용 (useEffect, useState, grid, Fragments )

 

 

<<과제>>

. useEffect() 인수에 따라 어느 타이밍이 되는지 스터디

. 왜 두번씩 출력되는 지 스터디

. 메뉴 짝수 홀수 마다 세팅왜다른지 찾기 

 

 

const NavBar = () => {

  const menu_list = ['로고', '메뉴1'];

 

  return (

    <Layout className="layout">

      <Header

        style={{

          display: 'flex',

          alignItems: 'center',

        }}

      >

        <Menu

          theme="dark"

          mode="horizontal"

          defaultSelectedKeys={['1']}

          items={new Array(2).fill(null).map((_, index) => {

            const key = index + 1;

            return {

              key,

              label: menu_list[key - 1],

            };

          })}

        />

      </Header>

    </Layout>

 

 

익명함수 .map()의 기본 파라미터 중 map(value, index) 사용형태

: _ value를 첫번째 인수로 받기는 하지만 사용하지 않는 상태

 

** 굳이 new Array 생성이 필요없다!

 

const NavBar = () => {

  const menu_list = ['로고', '메뉴1'];

 

  return (

    <Layout className="layout">

      <Header

        style={{

          display: 'flex',

          alignItems: 'center',

        }}

      >

        <Menu

          theme="dark"

          mode="horizontal"

          defaultSelectedKeys={['1']}

          items={menu_list.map((menu, index) => {

            const key = index + 1;

            return {

              key,

              label: menu,

            };

          })}

        />

      </Header>

    </Layout>

  );

};

 

: 배열을 지정해놓고 직접 value 값을 순회시키는 형태

=====================================================================

 

 

* Session 세션 : clientserver가 연결되어 있는 상태

보통 오랫동안 반응이 없다면 서버에서 자동으로 세션을 끊어버린다.

open API = 인증이 된 사람은 누구나 쓸 수 있는 공개 정보서버

 

 

TMDB API 관련 URL 형태

API

인기 영화

https://api.themoviedb.org/3/movie/popular?api_key={}&language=en-US

 

영화 상세 정보

https://api.themoviedb.org/3/movie/{영화아이디}?api_key={}&language=en-US

 

영화리뷰://api.themoviedb.org/3/movie/{영화아이디}/reviews?api_key={}&language=en-US&page=1

 

 영화 이미지

https://image.tmdb.org/t/p/original/wwemzKWzjKYJFfCeiB57q3r4Bcm.svg

https://image.tmdb.org/t/p/original/wwemzKWzjKYJFfCeiB57q3r4Bcm.png

https://image.tmdb.org/t/p/w500/wwemzKWzjKYJFfCeiB57q3r4Bcm.png

 

** Config.js에 링크 저장 및 출력 설정

 

export const API_URL = 'https://api.themoviedb.org/3/movie/'

export const API_KEY = '945147d70ad30bd77b0dd3656c8989e7'

export const IMAGE_BASE_URL = 'https://image.tmdb.org/t/p/'

 

 

** 랜딩페이지에 import

 

import { API_URL, API_KEY } from '../../Config'

 

function LandingPage() {

 

 

*** 동기 처리

consol.log(‘1. 시작’)

server에 데이터 요청; (서버가 응답하여 data를 보내줄때까지 계속 기다려야함)

: 서로의 시간을 맞춰 기다려주는 것이 동기

consol.log(‘2. 시작’)

 

HTML/CSSS로는 클라이언트 서버에 요청 못함 언어가 X

JS는 동적 처리가 기본 서버와 관련된 응답

=> 데이터에 관한 부분은 기다려야 한다.

 

*** 비동기 처리

비동기는 서버응답과 상관없이 있단 실행.

일정시간이 지났는데도 데이터 응답이 안오면 클라이언트가 다시 요청하기도함.

 

데이터에 대한 요청을 ‘JavaScript’에서는 비동기다.

펑셔널 컴포먼트로 실행되면 일단 데이터 요청을 하는 방식으로

 

{ useEffect }

컴포넌트가 특정한 시점에 특정한 단계가 실행되게 하고싶을 때 제어 하는 등 역할 : 리액트가 로드될 때

리액트 공식문서 hook(https://ko.legacy.reactjs.org/docs/hooks-effect.html)

 

useEffect(함수, []);

 

 

: 두 번째 인수로 [] (배열)이 들어가 있으면 이 페이지가 처음렌더링이 될

때 이 함수의 실행이 보장된다. (리렌더링 때 실행방지됨)

 

 useEffect(() => {

    const endpoint = `${API_URL}popular?api_key=${API_KEY}&language=en-US`

    fetch(endpoint)

      .then(response => response.json())

      .then(response => console.log(response));

  }, []);

 

 

{ useState }

useEffect로 나온 값을 저장하는 역할

 : 값과 set값이 같은 이름 스닙펫 사용

 

const [Movies, setMovies] = useState();

 

 

useState에 빈배열 저장해두고

 

  const [Movies, setMovies] = useState([]); // 빈배열 저장해두기

  // console.log('Movies : ', Movies); // undefined

 

 

상태 Movies에 영화 정보 (배열) 저장필요 setMovies

 

  const [Movies, setMovies] = useState([]); // 빈배열 저장해두기

  console.log('Movies : ', Movies);

 

  useEffect(() => {

    const endpoint = `${API_URL}popular?api_key=${API_KEY}&language=en-US`

    // console.log(endpoint);

    fetch(endpoint)

      .then(response => response.json())

      .then(response => setMovies(response.results));

  }, []);

 

 

 

** ‘페이지 첫 번째 영화 정보 저장추가

 

 

 

 

// 페이지의 첫 번째 영화 정보저장

  const [MainMovieImage, setMainMovieImage] = useState(null);

  console.log('MainMovieImage : ', MainMovieImage);

 

  useEffect(() => {

    const endpoint = `${API_URL}popular?api_key=${API_KEY}&language=en-US`

    // console.log(endpoint);

    fetch(endpoint)

      .then(response => response.json())

      .then(response => {

        setMovies(response.results);

        setMainMovieImage(response.results[0]);

      });

}, []);

 

 

* component – view - MainImage

: rafc (React Arrow Function Component (익명함수형태)) 스닙펫 사용

 

import React from 'react'

 

const MainImage = (props) => {

  return (

    <div style={{

      backgroundImage: `url(${props.image})`

    }}>

      <h2>제목</h2>

      <p>설명</p>

    </div>

  )

}

export default MainImage

 

 

MainImage‘props’ 변수와 ‘image’를 지정해주고

첫번째 영화정보가 있는 LandingPage에서 image url을 완성시켜 props로 받

아준다.

 

  return (

    <>

      <div style={{ width: '100%' }}>

        {/* Main Image */}

        <MainImage image={`${IMAGE_BASE_URL}w1280${MainMovieImage.poster_path}`} />

 

이미지 URL 형태

: https://image.tmdb.org/t/p/w500 ‘/wwemzKWzjKYJFfCeiB57q3r4Bcm.png’

(**이미지 경로는 기본 poster_path 안될 시 사용할 backdrop_path)

 

MainMovieImage.poster_path MainMovieImage 가 초기값 null이면 Error!

이므로 MainMovieImagetrue(!= null)면 뒤 실행하게

 

{/* Main Image */}

        {MainMovieImage &&

         <MainImage image={`${IMAGE_BASE_URL}w1280${MainMovieImage.poster_path}`} />}

 

**)JS에서 && 조건 왼쪽이 true면 오른쪽 실행

 

 

        {/* Main Image */}

        {MainMovieImage &&

          <MainImage

            image={`${IMAGE_BASE_URL}w1280${MainMovieImage.poster_path}`}

            title={MainMovieImage.title}

            overview={MainMovieImage.overview}

          />}

 

* 여러 속성을 prop으로 받는 것도 가능!

 

 

 

 

컴포넌트 디자인요소

Grid system

이러한 디자인 제공 사이트들은 기본column24개로 설정이 되어있다

 

 

따라서 코드에서     <col span={8} /> : 3분할

                               <col span={6} /> : 4분할

                               <col span={4} /> : 6분할    

 

 

gird gutter : 그리드간의 간격

반응형으로 웹브라우저 너비에 따라 grid 설정을 다르게 적용할 수 있다.

ex) { xs: 8, sm: 16, md: 24, lg: 32 } for responsive design.

 

 

*** 레이아웃 breakpoint width

*** bootstrap

grid option 참조 (width 기준 같음)

 

import { Col } from 'antd'

 

const GridCard = (props) => {

  /* {

  xs: '~`575px',

  sm: '576px~767px',

  md: '768px~991px',

  lg: '992px~1199px',

  xl: '1200px~1599px',

  xxl: '1600px~',

  } */

  return (

      <Col xs={24} md={8} lg={6}>

        <div>

          <a>

            <img

              src={props.path}

              alt={props.title}

            style={{ width: '100%' }}

            />

          </a>

        </div>

      </Col>

  )

}

 

export default GridCard

 

 

: breakpoint 반응형 너비는 <Col>에 설정

 

 

* gutter <Row> 에 설정 {[horizontal, vertical]} 형태

 

 <Row gutter={[10, 10]} />

 

 

 

유니크 키와관련해 편하게 키설정을 할 수 있는

**** fragments

<React.Fragments key={}>

fragments ( <> </> ) 로 표기하기도함(키 속성 미지원/그룹화 역할만 함)

: 컴포넌트 리턴에서 여러 자식들을 그룹화해주는 역할 (의미없는 <div>역할)

 

    return (

                <React.Fragment key={index}>

                  <GridCard

                    path={`${IMAGE_BASE_URL}w400${movie.poster_path}`}

                    title={movie.title}

                  />

                </React.Fragment>

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

반응형