⚛️ React/문제풀기 (코딩애플: React)

React : 최근 본 상품 만들기 (localStorage, map, JSON)

Zoeeey 2023. 7. 3. 21:17

조건

useNavigate훅을 사용한 상세보기 페이지("/detail/:id"형태)에 접근하면 해당 상품의 id 번호를 최근 본 상품에 업데이트한다.
여기서 최근 본 상품은 항상 옆에 떠 있는 플로팅 박스이다.


풀이

App.js

function App() {
  let getWatched = localStorage.getItem('watched');
  ...
  useEffect(() => {
    // 로컬스토리지 'watched'가 존재하지 않을 때만 빈 배열을 생성
    if (!getWatched)) {
      localStorage.setItem('watched', JSON.stringify([]));
    }
  }, []);
  ...
  return (
    ...
    // getWatched가 존재하면 Watched 컴포넌트를 랜더링
    // watchedItemsprop으로 getWatched값을 전달
    // getWatched값은 JSON 문자열이므로 JSON.parse()를 사용하여 JavaScript 객체나 배열로 변환
    {getWatched && <Watched watchedItems={JSON.parse(getWatched)}/>}
    ...
  );
}
function Watched(props){
  return (
    <>
      <div className="watchedlist">
        <h6>최근본상품</h6>
        {
          <!-- 삼항연산자로 값이 있을 시와 없을 시 구분 -->
          props.watchedItems === []
          ? props.watchedItems.map((value, index) =>
            <!-- key={} 빼면 오류남 -->
            <!-- key값은 반복되는 엘리먼트를 랜더링할 때 고유로 식별하기 위해 사용 -->
            <!-- index는 변할 수 있으므로, 변하지 않을 때만 권장됨 -->
            <div className="box" key={value.id}> 
              <p>{value}번째 상품</p>
            </div>
          )
          : <div className="box"><p>상품이 없습니다.</p></div>
        }
      </div>
    </>
  )
}

Detail.js

function Detail(props){
  ...
  useEffect(()=>{
    // 코드가 의도치 않게 두번 실행되는 걸 막아주는 코드
    // 이미 if문으로 이미 있는 id는 추가를 막고 있으므로 의미가 없다
    // setTimeout(()=> {setPagefade('end')}, 1000)

    let getWatched = localStorage.getItem('watched');
    getWatched = JSON.parse(getWatched);
    if (!getWatched.includes(selectedShoes.id)) {
      getWatched.push(selectedShoes.id);
      localStorage.setItem('watched', JSON.stringify(getWatched));
    }

    // 코드가 의도치 않게 두번 실행되는 걸 막아주는 코드2
    // return ()=>{
    //   setPagefade('')
    // }
  }, []);
  ...