useEffect를 사용하여 팝업창 띄우기
팝업창 만들기 (스타일)
팝업창은 position을 fixed로 설정하여 스크롤을 해도 화면에 고정되도록 한다.
z-index를 사용하여 화면의 최상단에 위치하도록 한다. (z-index는 position 값이 존재해야 적용된다. 단, position:static은 불가)

팝업창 만들기 (기능)
팝업창의 닫기와 오늘 하루 안 보기 기능을 만들기 위해서는 localStorage에 대해 알아야 한다.
localStorage를 사용하여 브라우저를 다시 실행해도 정보를 저장하도록 한다. localStorage.setItem
으로 데이터를 저장하는데, key는 homeVisited로 value는 팝업창을 띄운 시간에 24시를 더한 값(expires)이다.


useState를 통해 state를 관리한다.
기본값은 false로 setShowMainPop(false)가 되면서 팝업창 노출이 없다.
만약, 기본 값을 true로 할 경우, ‘오늘 하루 안보기’를 클릭하여도 리렌더링을 하면 팝업창이 나타난다.
HOME_VISITED 정수에 localStorage에서 homeVisited를 가져온다.
useEffect를 사용하여 ‘오늘 하루 안보기’ 버튼을 클릭하면, 리렌더링을 하여도 팝업창이 뜨지 않도록 한다.
today는 오늘의 시간(즉, 현재 시간)을 담은 정수이다.
handleMainPop은 화살표 함수에서 실행한 값을 저장한다.
만약, localStorage에 저장된 시간이 존재(true)하고 현재 시간(today)이 localStorage의 시간보다 작다면(true) return을 한다.
이때, return은 useState에서 기본값으로 세팅한 false이다. 즉, setShowMainPop(false)가 되면서 팝업창 노출이 없다.
localStorage의 시간: 이전에 팝업창이 떴을 때, ‘오늘 하루 보지 않기’를 클릭한 시간 + 24시간
다른 조건으로는, 만약 localStorage에 저장된 시간이 없거나(false) localStorage에 저장된 시간이 현재 시간(today)보다 작다면 setShowMainPop(true)를 실행하여 팝업창이 노출된다.
window.setTimeout에 실행할 함수는 handleMainPop이며 지연 시간은 0.1초이다. 0.1초 후에 해당 함수를 실행하도록 한다.
setTimeout()은 코드를 바로 실행하지 않고 일정 시간을 기다린 후에 실행할 때 사용한다. 첫번째 인자는 실행할 코드를 담은 함수, 두번째 인자는 지연 시간(ms)
❤️🔥 한 줄 요약
setShowMainPop(false) → 팝업창 노출 X
setShowMainPop(true) → 팝업창 노출 O
localStorage를 통해 ‘오늘 하루 안 보기’를 클릭한 시간 저장
참고
[React] 오늘 하루 안보기/ 24시간 동안 안보기 팝업 구현
자바스크립트의 setTimeout()과 setInterval() 함수
React ‘n일 동안 보지 않기’ 팝업 만들기
종합 소감
마켓컬리 클론코딩에 어떤 라이프사이클을 적용할 지 고민을 많이 했다.
그래서 라이프사이클을 통해 팝업창을 띄우기로 했다.
사실 직접 만들어서 해보려고 했지만… 나의 능력 부족으로 인해 ㅎ.. 다른 분의 코드를 참고하여 작성하였다.
대신의 해당 코드를 면밀히 이해하려고 했다. 그래서 내가 작성한 코드는 아니지만 어느정도 나의 지식으로 습득할 수 있었다.
Router 사용하기
router의 적용 순서는 다음과 같다.
BrowserRouter 연결 → 페이지 컴포넌트 만들기 → Route path 연결 → Link 컴포넌트 연결
- BrowserRouter 연결
App.js 파일에 react-router-dom에 내장되어 있는 BrowserRouter 컴포넌트를 불러온다.
- 페이지 컴포넌트 만들기
Market과 Beauty 페이지 컴포넌트를 만들었다.
- Route path 연결
Route 컴포넌트로 해당하는 URL을 지정한다. URL 지정은 path를 통해 지정한다.

- Link 컴포넌트 연결
Link 컴포넌트는 클릭하면 다른 주소로 이동시켜준다.
나는 페이지를 이동할 버튼이 Header 컴포넌트에 존재하기 때문에 Header.js에서 Link 컴포넌트를 연결했다.


문제 및 해결
Link 컴포넌트 사용시 밑줄 제거
- 문제
Link 컴포넌트를 사용하면 link 기본 스타일이 적용된다.
- 해결
Link 컴포넌트에
style=
을 사용하면 Link의 기본적인 스타일 속성이 사라진다.
참고
[React] Link to 밑줄 없애기
종합소감
이번 umc 4주차 워크북 미션은 기존에 만들었던 프로젝트에 라우팅을 적용해보는 것이었다. 이전에 강의로 공부를 한 적이 있긴 하지만… 영상의 도움없이 혼자 적용해 보는 것은 처음이라, 이전에 정리했던 정리글도 다시 확인하고 여러 글들을 서칭했다.
이번에 라우팅을 적용하고 다른 팀원들에게 적용하는 방법을 설명하면서 완벽하게 학습을 할 수 있었다. 혼자 서칭하면서 적용하기에 성공하고, 내가 학습한 내용을 다른 사람에게 설명까지 하니 완벽하게 나의 지식이 되어 만족스러웠다.
Swiper 기능 넣기
기존에 만들었던 함수를 작성하려고 했으나, 너무 복잡해지는 것 같아서 swiper 모듈을 설치하여 사용하기로 했다.


-
구현할 기능
5초 후에 자동으로 다음 배너 이미지로 변경하기,
화살표를 클릭하면 앞, 뒤로 배너 이미지 바꾸기
-
swiper 설치
-
swiper 및 css 불러오기
import { Swiper, SwiperSlide } from 'swiper/react';
import { Autoplay, Navigation, Pagination } from 'swiper';
import 'swiper/css';
import 'swiper/css/navigation';
import 'swiper/css/pagination';
나는 5초 뒤에 자동으로 다음 슬라이드로 변경되게 할 것이기 때문에 Autoplay를 불러왔다.
그리고 화살표를 클릭하여 슬라이드를 이동하게 할 것이기 때문에 Navigation과 Pagination을 불러왔다.
-
swiper 적용하기
export default function BannerContainer() {
...
return (
<div className="banner">
<div className="banner-img">
<Swiper
modules={[Navigation, Pagination, Autoplay]}
spaceBetween={50}
slidesPerView={1}
autoplay=
navigation
pagination=
onSlideChange={() => console.log('slide change')}
onSwiper={(swiper) => console.log(swiper)}
>
<SwiperSlide>
<Banner {...banner1} />
</SwiperSlide>
<SwiperSlide>
<Banner {...banner2} />
</SwiperSlide>
<SwiperSlide>
<Banner {...banner3} />
</SwiperSlide>
<SwiperSlide>
<Banner {...banner4} />
</SwiperSlide>
<SwiperSlide>
<Banner {...banner5} />
</SwiperSlide>
</Swiper>
</div>
</div>
);
}
이전 주차에 만들어뒀던 스타일이 존재했기 때문에 최대한 살리고자 .banner
와 .banner-img
박스는 그대로 두었다. 해당 박스 안에 Swiper 컴포넌트를 부르고 해당 컴포넌트안에 SwiperSilde를 원하는 갯수만큼 생성하면 된다.
Swiper에서 보일 슬라이드의 갯수는 1(sildePerview), 5초 뒤에 자동으로 슬라이드 이동(autoplay), 버튼을 통해 슬라이드를 이동하는 것은 true(navigation, pagination)로 설정했다.
나는 기존에 배너 이미지들의 스타일이 존재했기 때문에 해당 부분은 최대한 살리고, img의 link값만 변경해주기 위해서, SwiperSilde안에 Banner 컴포넌트(내가 만들었던 배너 이미지)를 넣어주었다.
Banner이미지는 img태그만 존재하기 때문에, 결과적으로는 SwiperSlide 컴포넌트 안에는 img태그가 들어있는 것이다.
-
Swiper를 적용하면서 문제점
-
css 파일을 가져올 때, 참고했던 문서들과는 불러오는 것이 달라서.. 에러가 엄청 떠서 약간 애를 먹었다..
그래서 일단, navigation, pagination은 삭제하고 swiper의 css만 불러오니 잘 되길래, 공식 문서처럼 navigation과 pagination의 css를 불러왔더니 잘 적용되었다.
-
img태그(Banner 컴포넌트)를 넣는 위치를 찾느라 시간이 좀 걸렸다.
처음에는 그냥 SwiperSlide 컴포넌트 안에 {…banner1}를 하는 바람에 당연히 에러가 발생했고.. 태그 사이에 넣었더니 또 당연히 에러가 발생했었다.
그러다가 Banner 컴포넌트를 다시 확인하고.. 생각해보니 Banner 컴포넌트를 모두 불러와서 banner1 (props)를 넣어줘야 내가 원하는 이미지의 링크가 잘 들어간 img 태그가 만들어지는 것을 깨닫고..! SwiperSlide 태그 사이에 Banner 컴포넌트를 넣었더니 잘 돌아갔다..!
-
참고자료
Swiper React Components
[React] 리액트에서 Swiper.js 를 사용해보자. Swiper 슬라이드 사용예제, Navigation의 arrow 버튼 커스텀하기
[#. React] React에서 swiper 사용하기, 배너 슬라이드 사용하기
useState를 사용하여, 버튼 클릭시 페이지 변환
useSate를 사용해서 변환하려고 하고 있으나 문제 해결 못함…뭔가 로직을 잘 못짜고 있는 느낌..?!
Header 컴포넌트에서 마켓컬리 버튼을 클릭하면 마켓컬리 페이지(Market 컴포넌트)로, 뷰티컬리 버튼을 클릭하면 뷰티컬리 페이지(Beauty 컴포넌트)만 보이게 하고 싶은데..
Market과 Beauty를 출력하는 것은 App.js에 있고, 버튼은 Header 컴포넌트에 있으니까..? 두개를 어떻게 이어야 할 지 잘 모르겠음…!!!
🚨해결!🚨
이벤트 핸들러를 안 해줘서 적용이 안됐다..! ㅜ..
내가 생각한 방식으로 useState 사용해서 페이지 전환이 되는 것은 맞았다!

App.js에 다음과 같이 코드 작성한다.
Header 컴포넌트에 props를 넘겨준다. onClick 하면 onChange가 실행되고 해당 값에 맞춰 page(setPage)가 변환된다. page의 값이 market이면 Market 컴포넌트 보여주기, beauty라면 Beauty 컴포넌트를 보여준다.
그리고 color에 들어오는 값이 market이라면 activeColor라는 이름의 클래스를 추가해준다. 값이 beauty일때도 마찬갖css에서 activeColor 클래스 추가시, 글자 색상이 보라색으로 작성했다.


종합소감
이전에 만들었던 걸 React로 다시 하느라 애를 먹은 부분이 많았다…
swiper라던가.. 페이지 변환이라던가…
그래도 내가 짰던 코드들을 컴포넌트로 분리하는 작업을 하면서 어떻게 컴포넌트를 나누면 좋을지 생각해보고, 직접 활용하면서 이런게 컴포넌트구나!를 깨달았다. 역시.. 따라하는게 아니라 직접 고심해보고 해야.. 머리에 잘 남는 것 같다.
그리고 state랑 props는 이론은 잘 알겠는데 실 적용을 못하겠었다. 그래서 특별 과외선생님(?)에게 물어봐서 실제 내 코드에 적용해보면서 조금은 이해가 되었다. 앞으로 react 쓸일은 많으니까 계속 만들어보면서 익혀야 겠다.
Node.js 버전 업데이트 하기
업데이트 적용 불가
위 방법을 통해 업데이트를 했으나, 해당 버전이 적용되지 않았다.

다음과 같이 installed와 active 두개의 경로가 존재했다.
새로 업데이트 한 것은 installed 경로이고 기존은 active 경로이다.
두 경로를 일치시켜야 적용이 된다.
React로 프로젝트를 만들던 중.. sass를 설치하고 나서 갑자기 Cannot find module loader 에러가 발생하였다..!
길게 에러 메세지가 떴는데 loader 뒤에도 babel 뭐시기 경로.. 이러는 걸 보면.. sass를 설치하고 뭔가 내부적으로 꼬인게..아닐까..? 싶은 추측중이다.
쨋든! 정확히 뭐가 문제인지는…! 잘 모르겠지만.. 서칭 끝에 해결 방법을 찾았다…!
해당 방법을 다 하고 npm을 다시 실행했더니! 잘 작동하게 됐다 ㅜ…!