//Cart.js
<div className="my-alert">
<p>지금 구매하시면 신규할인 20%</p>
<button>닫기</button>
</div>
이 알림창 UI의 상태를 state로 저장해서 닫기 버튼을 누르면 사라지도록 만들자!
//index.js
let defaultalert = true;
function reducer2(state = defaultalert, action){
return state
}
let store = createStore(combineReducers({reducer, reducer2}));
✨이때 combineReducers()를 써서 reducer 여러개를 한꺼번에 넘겨준다.
✨✨ reducer가 두 개 이상이면 store 데이터의 형식이 조금 달라지기 때문에 Cart.js에서 state를 props로 바꿔주는 함수(필자는 함수명을 stateToProps라고 지정함) 수정이 필요하다.
function stateToProps(state) {
return {
state: state.reducer,
alertState: state.reducer2
}
}
reducer가 여러개라면 잘 골라 써야함!!
다음으로 닫기 버튼을 누르면 알림창이 닫히게 설정한다.
//index.js
function reducer2(state = defaultalert, action){
if (action.type==='close'){
state = false
return state
}
return state
}
//Cart.js
{
props.alertState === true
?(<div className="my-alert">
<p>지금 구매하시면 신규할인 20%</p>
<button onClick={()=>{ props.dispatch({ type: 'close' })}}>닫기</button>
</div>)
:null
}
닫기 버튼을 누르면 사라짐
redux store에 온갖 데이터를 저장하는 것은 지양해야함!
알림창 UI같은 경우에는 Cart.js에서만 필요할 뿐, 다른 컴포넌트에서 필요 없음 useState를 이용하는 것이 가장 편리하고 권장되는 방법이다.
dispatch({type: 요청이름, payload: 보낼 데이터})
보낸 자료는 action 파라미터에 저장된다.
우선 주문하기 버튼을 눌렀을 때 함께 전송될 데이터를 만든다.
//Detail.js
<button className="btn btn-danger" onClick={() => {
props.dispatch({type: '항목추가', payload: { id: 2, name: '새로운상품', quan: 1 }});
}}>주문하기</button>
✨이때 props.dispatch()를 그냥 쓰면 에러가 나기 때문에 꼭 밑에서 connect 해주어야 한다 (당연히 connect함수를 위에서 import 해와야 함)
function stateToProps(state) {
return {
state: state.reducer,
alertState: state.reducer2
}
}
export default connect(stateToProps)(Detail);
//export default Detail;
그리고 이 데이터를 수정하는 reducer에 가서 '항목추가' 액션에 대한 조건문을 작성해준다.
//index.js
function reducer(state = defaultState, action){
if(action.type === '항목추가'){
let copy = [...state];
copy.push(action.payload); //payload에서 넘어온 것을 push해라
return copy
}
else if( action.type === '증가'){ //데이터 수정 조건
let copy = [...state];
copy[0].quan++;
return copy
}
else if (action.type === '감소'){
let copy = [...state];
copy[0].quan--;
return copy
}
else{
return state
}
}
그런데 Cart 페이지를 방문하면 추가한 데이터가 보이지 않음
-> 개발환경에서는 페이지를 이동하면 DB가 초기화 되기 때문이다.
-> 강제로 라우터 함수 history.push()를 이용해서 페이지를 이동시키면 데이터추가+페이지이동이 동시에 진행되면서 데이터가 초기화 되지 않음.
//Detail.js
<button className="btn btn-danger" onClick={() => {
props.dispatch({type: '항목추가', payload: { id: 2, name: '새로운상품', quan: 1 }});
history.push('/cart'); //강제로 페이지 이동
}}>주문하기</button>
props로 넘어온 데이터들을 살짝 가공해주면 된다.
<button className="btn btn-danger" onClick={() => {
props.dispatch({type: '항목추가', payload: { id: props.shoes[id].id, name: props.shoes[id].title, quan:1 }});
history.push('/cart'); //강제로 페이지 이동
}}>주문하기</button>
findIndex()
판별함수를 만족하는 첫 식별자를 반환한다.
반환타입은 Number, 값이 없다면 -1을 반환함.
function reducer(state = defaultState, action){
if(action.type === '항목추가'){
let copy = [...state];
//a는 copy안의 자료 하나하나를 뜻함
let idx = state.findIndex((a)=>{return a.id === action.payload.id});
if(idx>=0){
copy[idx].quan++;
}
else{
copy.push(action.payload);
}
return copy
}
}
강의의 예시코드랑은 조금 다른데 그냥 if else 안에 중복되던 코드를 앞 뒤로 뺐다