[React] 쇼핑몰 만들기(part2)-2

JH Cho·2022년 9월 6일
0

코딩애플

목록 보기
1/4

ajax

서버란?

유저가 데이터 달라고 요청하면 데이터를 보내주는 간단한 프로그램

  1. 어떤 데이터인지 (URL 형식으로)

  2. 어떤 방법으로 요청할지 (GET or POST)

예를 들어서 쇼미더럭키짱이라는 네이버웹툰을 보고싶으면

https://comic.naver.com/webtoon/list?titleId=783054 여기 URL로 GET요청하면 보내줍니다.

예를 들어서 독립일기라는 네이버웹툰을 보고싶으면

https://comic.naver.com/webtoon/list?titleId=748105 여기 URL로 GET요청하면 보내줍니다.

URL을 어떻게 알았냐고요?

네이버 웹툰 서버개발자에게 물어보거나 URL이 기재된 html 페이지를 찾아보거나 그러면 됩니다.

GET/POST 요청하는 법

GET 요청을 하는 가장 쉬운 방법은 브라우저 주소창을 이용하는 것.

POST요청을 날리고 싶으면 <form action='요청할URL' method='post'> 태그 이용하면 됨.

단 이렇게 하면 브라우저가 새로고침 됨.

AJAX?

: 서버에 GET, POST 요청을 할 때 새로고침 없이 데이터를 주고받을 수 있게 도와주는 브라우저 기능.

AJAX로 GET/POST 이용하는 방법
1. XMLHttpRequest(구식 문법)
2. fetch() - 최신 문법
3. axios 외부라이브러리

  • axios 써보자

    npm install anxios

import axios from 'axios'

function App(){
  return (
    <button onClick={()=>{
      axios.get('https://codingapple1.github.io/shop/data2.json').then((결과)=>{
        console.log(결과.data)
      })
      .catch(()=>{
        console.log('실패함')
      })
    }}>버튼</button>
  )
}
  • then/ catch?
    .then (GET 성공시 실행 함수)
    .catch(실패시 실행 함수)

  • 버튼 누르면 서버에서 받은 데이터를 이용해서 상품 더 보여주기.

    let [btnCount, setBtnCount] = useState(0);
    //버튼 카운트 스테이트를 만들어주고.
    
      axios.get(
        `https://codingapple1.github.io/shop/data${btnCount + 2}.json`
        //이렇게 백틱써도 되지만 if esle if로 카운트마다 조건걸어주고
        // 각 url을 써줘도 될듯. 근데 url이 많다면?
    
     //그리고 버튼에는 카운트가 증가함에 따라 조건을 걸어두고 disabled되게 함
    <button disabled={btnCount === 2 ? true : false}>
        
        
                   

    리액트에서 서버와 통신하려면 ajax 2 : post, fetch

    post 요청하기

    axios.post('URL', {name : 'kim'})

    이렇게 하면 객체 자료가 전송되고 GET과 마찬가지로 .then()을 이용하여 성공시 실행 코드를 붙일 수도 있다.

    동시에 ajax 요청 여러개

    Promise.all([axios.get('URL1'), axios.get('url2')])
    이것도 .then() 이용 가능.

    원래는 서버와 string만 주고 받을 수 있음

    "{"name" : "kim"}" 이런식으로 obj/arr에 따옴표를 치면 됨.

    이를 JSON이라고 함.
    JSON은 string 취급을 하기에 서버와 자유롭게 주고 받을 수 있음.

    그래서 실제로 결과.data를 출력해보면 따옴표쳐진 JSON이 나오지 않고
    obj/arr가 잘 나오는데
    axios 라이브러리가 JSON -> obj/arr 변환 작업을 자동으로 적용해줘서 그렇다.

    자바스크립트 문법 fetch

    fetch('URL').then(결과 => 결과.json()).then((결과)=>{console.log(결과))
    axios 라이브러리를 안쓰고 자바스크립트의 fetch 함수를 사용하면 이렇게 JSON 변환 작업이 필요함. 라이브러리 만세.

    리액트 탭 UI 만들기

    리액트 부트스트랩에서 버튼 UI 갖고왔음

    내용 div을 만들었고 state도 생성했음.

        {=== 0 ? <div>내용0</div> : null}
        {=== 1 ? <div>내용1</div> : null}
        {=== 2 ? <div>내용2</div> : null}

    이런식으로 삼항연산자를 배치해도 되지만 더 좋은 방법 없을까.

function TabContent(){
  if (=== 0){
    <div>내용0</div>
  }
  if (=== 1){
    <div>내용1</div>
  }
  if (=== 2){
    <div>내용2</div>
  }
}
function TabContent({}) {
  return [<div>내용0</div>, <div>내용1</div>, <div>내용2</div>][];
}

애니메이션 주기(transition)

function TabContent({}) {
  let [효과, 효과변경] = useState("");
  useEffect(() => {
    
    효과변경("end");
    return () => {
      효과변경(" ");
    }; // 이런식으로 클린업 함수에 먼저 주면 안될까? 했는데
     // 리액트의 automatic batching 기능 때문에
    //효과변경('') -> 효과변경('end') 이렇게 실행되는게 아니라
    // 이전 변경 스테이트는 무시하고 최종 변경스테이트함수를 기준으로만 재렌더링 함.
  }, []);
  return (
    <div className={"start " + 효과}>
      {[<div>내용0</div>, <div>내용1</div>, <div>내용2</div>][]}
    </div>
  );
}
---------
    
    useEffect(() => {
 	 setTimeout(() => {
      효과변경("end");
    }, 100);
    return () => {
      효과변경(" ");
    }; //이런식으로 텀을 두고 실행해주면 된다.
  • 과제 : detail 페이지 실행시 transition 적용
  let [state, setState] = useState("");
  useEffect(() => {
    setState("end");
    return () => {
      setState(" ");
    };
  }, []); //컴포넌트 마운트때 end붙이고 unmount때 ''으로 실행.

<div className={"container start " + state}>

좀 더 정확히 useEffect에 대해 공부하고 따로 정리하는 글 남겨봐야겠음.

Context API


props는 부모 -> 자식만 가능하다.
부모 -> 자식 - > 자식도 가능함

근데 이거 귀찮다.

뭔가 방법이 없을까?

  1. Context API (기능정도만 숙지하고 간단한 프로젝트에서 써보는 정도)
  2. Redux(외부 라이브러리 : 추천)

Context API

  • Context 생성하기
(App.js)

export let context = createContext();
// state 보관함, 다른 컴포에서도 사용가능하게 export

function App(){
  let [재고, 재고변경] = useState([10,11,12]);
  let [shoes, setShoes] = useState(data);

  return (
    <Context1.Provider value={ {재고,shoes (원하는 state 넣기)} }>
      <Detail shoes={shoes}/>
    </Context1.Provider>
    // Context로 감싼 모든 컴포넌트와 그 컴포넌트의 자식들은
   // value에 할당해준 state들을 props 전송 없이 사용할 수 있다.
  )
}
  • Context import 하기
import {useState, useEffect, useContext} from 'react';
import {Context1} from './../App.js';

function Detail(){
  let {재고, shoes} = useContext(Context1)
  // destructuring 으로 할당해도 되고
  let a = useContext(Context1)
  //이런식으로 변수에 할당해서 사용해도 된다.

  return (
    <div>{재고}</div>
  )
}

Detail 컴포의 자식 컴포에서도 useContext 할당해주고 사용해보면 잘 나온다.

console.log(shoes[0], 재고[0]); 
//이벤트 함수 내에 위치시키고 찍어보면 잘 나옴.
  • props보다 불편하게 느낀다?
    props써라.
    Context API는 중첩해서 사용한 컴포가 많을 때 편리한 문법이다.
  • Context API의 단점
  1. state 변경 시 쓸데없는 컴포까지 다 재렌더링 됨.
  2. useContext()를 사용하고 있는 컴포는 나중에 다른 파일에서 재사용 시 Context Import가 귀찮음. -> 그래서 외부 라이브러리 Redux 씀.
profile
주먹구구식은 버리고 Why & How를 고민하며 프로그래밍 하는 개발자가 되자!

0개의 댓글