현재 기업협업으로 리액트로 만든 웹페이지를 디버깅 중이다.
항상 현재 위치한 페이지를 입력하다 나가려고 하면 모달창이 뜨게 만들었다. 그러나, 유저가 포인트가 부족한 경우도 고려해서 그 경우에는 모달창이 아예 안뜨게 만드려는 것이 목표다.
지금 위 케이스는 유저가 부족한 포인트를 가지고 있고 이 상태에서 포인트 구매 버튼이 생기고 이것을 클릭하면 바로 포인트 구매 page로 이동하게 만들어야 한다..(정말로 나가시겠습니까?라는 모달창은 뜨면 안된다)
위 같은 경우는 포인트가 부족한 유저가 정보를 입력했지만 포인트 구매 버튼을 누르지 않고 다른 페이지로 이동하려고 하는 경우다.
(모달창이 떠야 한다!)
우선 이렇게 로직을 생각해 놓고 코드를 짜야한다!🙃
현재 모달창이 뜨는 것과 관련된 코드는 CreateEvent.js
에 작성되어있다. 포인트가 부족하여 포인트 구매와 관련된 컨테이너와 그 안에 버튼이 생기는 부분은 NotEnoughCost.js
에 작성되어있다.
❗️포인트가 부족할 때도 모달에 대한 정보가 필요하다. 그래서 이 정보를 넘겨줘야 하는데 어떻게 넘겨줄 수 있을까?
리덕스를 쓰게 되면 각각의 컴포넌트를 다 안 건드려도 되고 스토어에 저장을 하니 구조적으로도 간결하다.
리덕스에 대한 이론 공부만 해보다가 실제로 코드로 작성해보려니 많은 어려움이 있었다 ㅠㅠ 리덕스박사 동기의 설명을 듣고 리덕스 코드 작성 성공!(그러나 아직 갈길이 먼 리덕스의 세계ㅠㅠ)
우선 포인트를 체크해서 포인트가 부족한 경우, 포인트 구매버튼을 누르면 모달창이 뜨지 말아야 한다. 이와 관련된 부분의 액션,리듀서 함수를 따로 pointCheckModule.js
파일로 만들었다.
(Action)
isCheckPoint라는 함수는 point를 인자로 받는다.type은 어떤 액션을 나타내는지 알 수 있게 한다.
우리는 포인트를 체크할 거니까 CHECKPOINT!(위에 변수로 만들어서 사용하는 것이 좋다. 대문자로 쓰자)
payload는 변경 가능한 key값으로 타입 속성의 그 내용을 말한다. 이제 액션 함수를 작성했으니 아래에 리듀서 함수도 작성해보자.
(dispatch)
먼저 dispatch가 실행된다. dispatch가 실행되면 액션 객체는 리듀서로 전달 되고 리듀서 내에 미리 정의해둔 조건문과 action.type에 따라 스토어가 업데이트 된다.
(Reducer)
state에 초기값 설정한 값,action을 인자로 받는 checkPointReducer함수가 실행된다.
switch조건문 안에 case가 CHECKPOINT인 경우, action.payload를 리턴 그리고 디폴트인 경우,이전 상태를 그대로 리턴한다.
그 다음으로 해야할 것은 module안의 index.js에 위 작성한 값들을 import해서 전체 코드에 뿌려줄 수 있는 초기작업을 해야한다.
import checkPointReducer from "./PointCheckModule";
작성해주고 combineReducers에 checkPointReducer
까지 추가해주면 성공!
🟢 여기서 그렇다면 combineReducers는 도대체 뭘까?
combineReducers 헬퍼 함수는 서로 다른 리듀싱 함수들을 값으로 가지는 객체를 받아서 createStore에 넘길 수 있는 하나의 리듀싱 함수로 바꿔준다. 즉 많은 reducer들을 하나로 합쳐 하나의 reducer로 관리할 수 있게 한다.
✔️ 그 다음으로 NotEnouthCost.js
파일로 가서 해야할 것은{isCheckPoint}
액션함수를 import먼저 해준다.
import { isCheckPoint } from "../../../../../../src/modules/PointCheckModule";
그다음으로 dispatch가 실행되야 하니 아래같이 작성해줘야 한다.
useDispatch함수는 스토어에 액션 객체를 전달하는 함수이다.
const dispatch = useDispatch();
그 다음에는 포인트 구매버튼에 위 함수를 실행시켜준다.
<BuyCreditSection
onClick={() => {
dispatch(isCheckPoint(true));
}}
>
포인트 구매
</BuyCreditSection>
dispatch()함수 안에 isCheckPoint함수가 실행되고 isCheckPoint는 true라고 설정해준다. (참고로 리듀서함수를 보면 초기값은 false로 작성해주었다)
✔️ 그 다음으로는 상위 컴포넌트인 CreateEvent.js
로 가보자. 여기서 추가로 작성해줘야 하는 부분은 아래와 같다.
const pointCheck = useSelector(store => store.checkPointReducer);
useSelector를 이용해 store에 저장된 checkPointReducer를 가져온다.
페이지 이동 관련 useEffect함수 안에서,if문 추가.
만약 리듀서값이 있으면 creditsPage로 이동한다.
useEffect(() => {
//checkPointReducer값이 있으면 CreditsPage로 이동
if (pointCheck) {
window.location.href = "/CreditsPage";
}
//현재 페이지에서 이동하려고 할 때
if (isLeave && lastLocation) {
return history.push(lastLocation);
}
}, [history, isLeave, lastLocation, pointCheck]);