REST 파라미터

money랑 hobby를 지우고 싶다면??

기존 지식으로는

const newCHild ={
...child
money: 1000,
hobby: soccer
}

이렇게 바꿀수는 있었지만 지우는건 몰랐음

delete child.money
delete child.hobby

이렇게 하면 지울 수 있음 , 자바스크립트에서는 완전 좋은 방법은 아님, 왜냐면 원본을 건드리는 방식이기 때문

REST 파라미터가 뭐냐

money와 hobby를 뺀 ...rest를 넣겠다 이렇게 하면 이게 REST파라미터다
이렇게하면 rest로 child에들어오게된다.

실제로 해보자

rest를 newChild로 해도 그냥 rest파라미터일뿐 이름은 달라도 상관없다

브라우저 저장소

브라우저 저장소 에는 세가지가 보통 있음

cookie, LocalStorage, SessionStorage
LocalStorage 는 state를 저장하는데 쓰였음(새로고침해도 사라지지않게)
SessionStorage는 비슷하지만 브라우저를 끄면 사라짐

cookie 브라우저를 새로고침할때마다 쿠키에 있는 값이 자동으로 딸려들어간다는 것이 다름
우리도 알게 모르게 백엔드 API로 날라가고있었음, 위티는 reuest.header

쿠키에다가 너무 많을걸 담으면 데이터양이 많이 늘어날 수 있음

하지만 서버와 지속적으로 연결을 하고싶으면 쿠키를 사용하는게 좋음
대표적으로 Refresh토큰같은건 알아서 새로고침하게 해줌

실무로는 전부 LocalStorage에 담아놓고 비회원이면 비회원으로 담은 제품을 장바구니에 넣겠습니까 / 아니면 로그인한대로 다 넣어주기

이렇게 됨
셋 다 한번씩 써보자

로컨스토리지랑 세션스토리지의 경우 사용법은 비슷하다

export default function BrowserStroagePage() {
  function onClickSetCookie() {
    document.cookie = "aaa=철수";
  }

  function onClickSetLocalStorage() {
    localStorage.setItem("bbb", "영희");
  }

  function onClickSetSessionStorage() {
    sessionStorage.setItem("ccc", "훈이");
  }

  function onClickGetCookie() {}

  function onClickGetLocalStorage() {}

  function onClickGetSessionStorage() {}

  return (
    <>
      <button onClick={onClickSetCookie}> 쿠키에 저장하기 </button>
      <button onClick={onClickSetLocalStorage}>
        {" "}
        로컬스토리지에 저장하기{" "}
      </button>
      <button onClick={onClickSetSessionStorage}>
        {" "}
        세션 스토리지에 저장하기{" "}
      </button>
      =====================================
      <button onClick={onClickGetCookie}> 쿠키에 있는 값 가져오기 </button>
      <button onClick={onClickGetLocalStorage}>
        {" "}
        로컬스토리지에 있는 값 가져오기{" "}
      </button>
      <button onClick={onClickGetSessionStorage}>
        {" "}
        세션스토리지에 있는 값 가져오기{" "}
      </button>
    </>
  );
}

이렇게 어플리케이션 부분에 가면 로컬스토리지, 세션스토리지, 쿠키들에 다 저장이 되어있다.

쿠키 안에도 되게 여러 기능들이 있음 path, expires, size, httponly 등등
이건 refreshtoken 을 하면서 배워보고 넣었다 꺼내기를 해보는게 좋음

function onClickGetCookie() {
    const mycookie = document.cookie;
    console.log(mycookie);
  }

  function onClickGetLocalStorage() {
    const bbb = localStorage.getItem("bbb");
    console.log(bbb);
  }

  function onClickGetSessionStorage() {
    const ccc = sessionStorage.getItem("ccc");
    console.log(ccc);
  }

근데 쿠키만 통채로 가져오는 것 같아서 = 을 기준으로 짤라주는게 좋은 것 같음

또 이렇게 추가를 할 수 있다. 그런데 가져오면

aaa=철수; ddd=맹구; zzz=짱구

이렇게 나온다

물론 이걸 라이브러리로 고칠 수 있지만 또 다른 다운로드를 해야하기 때문에 split을 쓰는게 좋음

  function onClickGetCookie() {
    // "aaa=철수"; "ddd=맹구"; "zzz=짱구".split(";").filter(el => el.startsWith("zzz=")) [0]
    const zzz = document.cookie
      .split("; ")
      .filter((el) => el.startsWith("zzz="))[0]; // "zzz=짱구"가 나옴
    console.log(zzz.split("=")[1]); // zzz=짱구 에서 1번째 값을 가져오기//
  }

한번만 split을 하게 되면 zzz=짱구라고 나오게된다.
그럼 그 값을 =을 기준으로 다시 나눈 후 첫번 째 값(0번째는 zzz)을 가져오면 짱구가 나오게된다.

이렇게 다른 스토리지에 비해서 쿠키는 통채로 가져오는 성격 때문에 split을 두 번 이용해서 가져와야한다.
다양한 서비스를 개발해서 쿠키를 통한 개발을 하고싶다면 쿠키를 가져오는게 맞으나
작은서비스는 굳이 가져올 필요가 없음 , 로컬스토리지를 활용하는게 좋음

특성에 맞게 활용하는게 중요함

로컬스토리지를 활용해서 비회원장바구니를 담아보자

// 1. 게시물 목록 불러오기
// 2. 함수를 실행해서 몇번째 게시물인지 확인 후 저장
import { useQuery, gql } from "@apollo/client";
import {
  IQuery,
  IQueryFetchBoardArgs,
} from "../../src/commons/types/generated/types";

const FETCH_BOARDS = gql`
  query fetchBoards {
    fetchBoards {
      _id
      writer
      title
    }
  }
`;

export default function BasketPage() {
  const { data } = useQuery<Pick<IQuery, "fetchBoards">, IQueryFetchBoardArgs>(
    FETCH_BOARDS
  );

    const onClickBasket = (el) => () => {
        console.log(el)
        // localStorage.setItem("basket", el)
    }


  return (
    <>
      {data?.fetchBoards.map((el, index) => (
        <div key={el._id}>
          <span>{index + 1}</span>
          <span>{el.writer}</span>
          <span>{el.title}</span>
          <button onClick={onClickBasket(el)}>장바구니담기</button>
        </div>
      ))}
    </>
  );
}

이제 클릭하면 localStorage.setItem으로 가져오는데 가져올 아이템이 배열이다. 어떻게하는게 좋을까?
HOF(high order function)를 사용한다
클로저의 특성에 이해서 el, event 다 함수에서 다 사용이 가능함
일단 여기까지 해두고 el에 뭐가 들어오는지 보자

이런 정보가 들어온다
localStorage.setItem("basket", JSON.stringify(el));
이렇게하면 basket이라는 키에 el하나를 스트링으로 담아주는데
한번에 하나씩 밖에 저장이 안된다.(애플리케이션 부분을 확인하면 계속 바뀜)

그럼 어떻게할까? -> 로컬스토리지에서 basket을 꺼내온다

  const onClickBasket = (el) => () => {
    console.log(el);

    const baskets = JSON.parse(localStorage.getItem("basket")) || [];
    baskets.push(el);

    localStorage.setItem("basket", JSON.stringify(baskets));
  };
  

근데 중복된 데이터도 계속 가져온다. 중복처리를 해보자

   let isExists = false;
   baskets.forEach((basketEL) => {
     if (el._id === basketEL._id) isExists = true;
   });
   if (isExists) {
     alert("이미 장바구니에 담으셨습니다!");
     return;
   }

const { __typename, ...newEL } = el;
baskets.push(newEL);

이렇게하면 타입네임을 제외하고 값을 출력시킬 수 있다

로그인해서 확인되면 로그인 이후 페이지도 만들어보자
(물론 로그인페이지로 넘어가는 부분도 만들어야한다)

  function onClickLogin() {
    alert("로그인에 성공하였습니다.");
    const baskets = JSON.parse(localStorage.getItem("basket") || "[]");
    if (baskets.length) {
      const result = confirm(
        "장바구니에 담으신 상품이 있습니다. 장바구니 페이지로 이동할까요?"
      );
      if (result) router.push("26-03-basket-logged-in");
    }
  }
  
  //아래리턴부분에 추가
<button onClick={onClickLogin}>로그인하기</button>

  
import { useEffect, useState } from "react";
import { IBoard } from "../../src/commons/types/generated/types";

export default function BasketLoggedInpage() {
  const [basketItems, setbasketItems] = useState<IBoard[]>([]);

  useEffect(() => {
    const baskets = JSON.parse(localStorage.getItem("basket") || "[]");
    setbasketItems(baskets);
  }, []);

  return (
    <>
      <h1>비회원으로 담은 나만의 장바구니!!</h1>
      {basketItems.map((el, index) => (
        <div key={el._id}>
          <span>{index + 1}</span>
          <span>{el.writer}</span>
          <span>{el.title}</span>
        </div>
      ))}
    </>
  );
}

요약
브라우저 저장소
변수에 데이터를 넣어놓으면 새로고침할때 저장된 데이터가 날아가는 현상은
HTML, CSS, JS를 다시 다운로드 받아서 화면에 새로 그리기 때문

데이터를 유지하기위해 브라우저 저장소에 저장해야함
브라우저 저장소는 쿠키, 로컬스토리지, 세션스토리지가 있음

쿠키: 저장된 데이터가 Backend-API 요청시에 함께 보내짐
로컬스토리지: 브라우저를 껐다가 다시 켜도 저장 정보가 남아있음
세션스토리지: 브라우저를 껐다가 다시 켜면 저장 정보가 사라짐

이걸 적용하면

  1. 비회원으로 장바구니 담기
    비회원은 로그인 전이므로 백엔드에서 어떤 유저가 장바구니에 무엇을 담고 있는지 기록하기 애매하지만 로컬스토리지에 임시로 저장해놓으면 로그인에 성공했을 때 미리 담아놓은 장바구니를 쉽게 가져올 수 있음

  2. 오늘 본 상품 보여주기
    오늘 본 상품 또한 오늘 클릭했던 상품들만 로컬 스토리지에 저장해 놓으면 가능
    물론 브라우저를 껐다가 다시 들어올 수도 있으므로 세션트토리지보다는 로컬스토리지가 이득

profile
개발자 새싹🌱 The only constant is change.

0개의 댓글