본문 바로가기

Studying/React

리액트 기초부터 쇼핑몰 프로젝트까지! Part2 #6 localStorage

* 리액트에서 자주 쓰는 if문 작성패턴 5개

: JSX 이용해서 html 작성할 때 if문 대신해서 사용할 수 있는 5가지

 

- component 안에서 쓰는 if / else

function Component() {
  if ( true ) {
    return <p>참이면 보여줄 HTML</p>;
  } else {
    return null;
  }
}

if를 function 안에 넣어서 return 안에서 못 쓰니까 return + JSX 전체를 내 뱉는 if문을 작성해서 사용

function Component() {
  if ( true ) {
    return <p>참이면 보여줄 HTML</p>;
  } 
  return null;
}

else와 중괄호 생략 가능. (왜냐면 자바스크립트 function 안에선 return 이라는 키워드를 만나면 return 밑에 있는 코드는 더이상 실행되지 않음)

 

- JSX 안에서 쓰는 삼항연산자 (tenary operator)

조건문 ? 조건문 참일 때 실행할 코드 : 거짓일 때 실행할 코드

 

- && 연산자로 if 역할 대신하기

&& 연산자

: 자바스크립트는 &&로 연결된 값들 중에 처음 등장하는 falsy 값을 찾아주고 그게 아니면 마지막값을 남겨줌.

 다 true일 때만 true고 false값이 없으면 자료형 값을 남겨주고 false가 있으면 무조건 false값을 남김.

true && true;
// true

true && false;
// false

true && '안녕';
// '안녕'

false && '안녕';
// false

true && false && '안녕';
// false

 

function Component() {
  return (
    <div>
      {
        1 === 1
        ? <p>참이면 보여줄 HTML</p>
        : null
      }
    </div>
  )
} 

function Component() {
  return (
    <div>
      { 1 === 1 && <p>참이면 보여줄 HTML</p> }
    </div>
  )
}

 

- switch / case 조건문

if문이 중첩된 경우에 가끔 씀.

function Component2(){
  var user = 'seller';
  switch (user){
    case 'seller' :
      return <h4>판매자 로그인</h4>
    case 'customer' :
      return <h4>구매자 로그인</h4>
    default : 
      return <h4>그냥 로그인</h4>
  }
}

단점

조건식란에서 변수 하나만 검사할 수 있음.

 

- object / array 자료형 응용

 

현재 state가 info면 <p>상품정보</p>

현재 state가 shipping이면 <p>배송정보</p>

현재 state가 refund면 <p>환불약관</p>

 

이러한 여러 가지를 state 변경 안 하고 object에 내가 보여주고 싶은 html을 다 넣음

그 다음에 object{} 뒤에 [] 대괄호 붙여서 'key값이 현재상태인 자료를 뽑겠다' 라고 씀.

그러면 현재상태가 info / refund / shipping 등으로 바뀔 때마다 저장된 <p>태그가 보임.

function Component() {
  let 현재상태 = useState('info');
  return (
    <div>
      {
        { 
           info : <p>상품정보</p>,
           shipping : <p>배송관련</p>,
           refund : <p>환불약관</p>
        }[현재상태]
      }

    </div>
  )
}

 

 

* localStorage 이용해서 최근에 본 상품 기능 만들기

 

새로고침해도 state데이터가 리셋되지 않도록 하려면?

서버로 보내서 DB에 저장해야됨.

서버나 DB 지식 없으면 ?

localStorage(user의 browser에 몰래 정보를 저장하고 싶을 때 쓰는 공간) 이용

 

- > chrome 검사 들어가서 Application 탭 누르면 확인 가능

사이트마다 5MB 정도의 문자 데이터를 저장할 수 있음.

object 자료처럼 key / value 형태로 저장 가능.

user가 browser 청소하지 않는 이상 반영구적으로 남아있음.

Session Storage도 똑같은데 얘는 브라우저 끄면 삭제됨.

 

 

* localStorage 문법

 

- 기본 문법

'데이터이름' == key

'데이터' == value

// 데이터 추가
localStorage.setItem('데이터이름', '데이터');

// 데이터 불러오기(읽기)
localStorage.getItem('데이터이름');

// 데이터 삭제
localStorage.removeItem('데이터이름')

// 데이터 수정
let 꺼낸거 = localStorage.getItem('데이터이름') // 원래 있던 거 불러 옴
꺼낸거 = JSON.parse(꺼낸거) // 꺼낸 거를 JSON -> array , object 자료로 바꿈
꺼낸거.push(추가하고싶은데이터)  // 내용 추가
localStorage.setItem('데이터이름', JSON.stringify(꺼낸거)) // 수정 데이터 저장

 

- array / object 자료 저장하고 불러오는 방법

 

문자만 저장할 수 있기 때문에 JSON으로 변환해서 저장함.

JSON은 그냥 따옴표 친 array / object 자료, 문자취급받음.

데이터를 꺼낼 때는 다시 JSON -> array / object로 변환한 후에 꺼내야 됨.

 

JSON.stringify( { array / object } ) 

: JSON으로 변환 시켜주는 함수

localStorage.setItem( 'obj', JSON.stringify({name:'kim'}) )


// > "{"name":"kim"}"

 

JSON.parse()

: JSON을 array / object로 변환해주는 함수

var a = localStorage.getItem('obj');

var b = JSON.parse(a)

 

 

- 모든 state를 localStorage에 자동 저장해주는 외부 라이브러리

redux-persist

 

 

숙제 : 

- 최근 본 상품 UI 만들기

: 유저가 누른 상품의 번호를 localStorage에 저장해보기

 

팁) 사이트에 접속하면 localStorage에 []가 하나 있어야 자료 추가가 쉬움.

function App() {

  useEffect(()=>{
   localStorage.setItem('watched', JSON.stringify( [] )) 
  } , [])

 

- 내가 생각한 방법

useParams()를 사용해서 유저가 입력한 값을 가져온 후 localStorage에 저장하기

// (App.js)

import { useParams } from 'react-router-dom'



function App() {

  let {id} = useParams();
  
  useEffect(()=>{
    localStorage.setItem('watched', JSON.stringify( [] ))
  }, [])

  localStorage.setItem('watched',JSON.stringify({id}));

-> 근데 저장이 안 됨..

이따구로만 됨

 

-> Detail.js페이지에 접속해야 되는 거니까 하단을 Detail.js에 입력해야됨

 localStorage.setItem('watched',JSON.stringify({id}));

입력하고 나면 저장되어 있음.

 

- 코딩애플 방법

: localStorage에 접속한 상품의 id를 처음에 만들어둔 배열에 추가해줘야되는데, 내가 한 방법은 그냥 object로 대체되어버림.

=> 수정 문법 사용해야됨

// (Detail.js)

function Detail(props){

 useEffect( ()=> {
      
      let 꺼낸거 = localStorage.getItem('watched') // 수정할 원본 데이터 불러오기
      꺼낸거 = JSON.parse(꺼낸거) // JSON -> array , object 로 변경
      꺼낸거.push(찾은상품.id)  // 원본데이터에 수정할 데이터 추가하기
      localStorage.setItem('watched', JSON.stringify(꺼낸거)) // 수정한 데이터 다시 저장

     }, [])
     
	 return()}

strictmode에 의해 두 번씩 실행됨

 

추가 공부) 똑같은 상품 재접속했을 때 번호가 중복되는 것을 방지하려면 ? (택 1)

 

- 조건문 사용

 

- Set자료형 사용

array -> Set(중복을 제거한 array) -> array

 

사용법

new Set( array 자료 )  // 알아서 중복 제거해주는 Set 자료형으로 바꾼 뒤
Array.from( array 자료 ) // 다시 array 자료로 바꿈

 

// Detail.js


useEffect( ()=> {
      
      let 꺼낸거 = localStorage.getItem('watched') // 수정할 원본 데이터 불러오기
      꺼낸거 = JSON.parse(꺼낸거) // JSON -> array , object 로 변경
      꺼낸거.push(찾은상품.id)  // 원본데이터에 수정할 데이터 추가하기

      // 중복 제거 한 뒤 다시 저장
      꺼낸거 = new Set(꺼낸거)
      꺼낸거 = Array.from(꺼낸거)
      localStorage.setItem('watched', JSON.stringify(꺼낸거)) // 수정한 데이터 다시 저장

     }, [])

 

-> 하단과 같은 에러가 발생함

 

-> 질문 페이지보니까 이거 삭제하면 된다고 함.

import { set } from "immer/dist/internal.js";

왜 되는지는 모르겠는데 set이 new Set에 영향을 미쳐서 발생한 에러인건지..

Module not found는 뭔가 경로가 잘못된 걸 말한다는데 나중에 더 찾아봐야겠음.

 

추가 기능 )

1. 새로고침해도 초기값으로 돌아가지 않게 하기

2. 최근본상품 UI 디자인해서 받아온 데이터 보여주기