Front-end/React
[React] 코딩애플 blog-part3-4 (장바구니 기능 완성)
hyebin Lee
2022. 1. 9. 21:52
메인페이지 <Card> 누르면 페이지 이동시키기
<Card onClick={()=>{ history.push('/detail/0') }} />
이렇게 해도 실행이 되지 않는다.
이유는 <컴포넌트>는 div가 아니기 때문에 onClick은 속성을 달아도 동작하지 않을 수 있다.
<Card> 컴포넌트를 정의한 곳으로 가서 div에 직접 onClick을 달아주시면 문제 해결
function Contents(props) {
let inventory = useContext(inventoryContext);
let history = useHistory();
return (
<div
className="col-md-4"
onClick={() => {
history.push("/detail/" + props.sticker.id);
}}
>
어쩌구
</div>
);
}
/detail 뒷부분에 props.sticker.id로 동적으로 수정
장바구니 페이지 +/- 버튼 완성하기
<button
onClick={() => {
dispatch({
type: "수량증가",
payload: {
id: i,
},
});
}}
>
+
</button>
dispatch할 때 {데이터 : a.id } 라는 오브젝트도 함께 전달
(index.js)
function reducer(state = defaltState, action) {
if (action.type === "수량증가") {
let copy = [...state];
copy[action.payload.id].quan++;
return copy;
}
(이하 나머지 if문들)
reducer 내부를 수정하기!
보낸 데이터를 가지고 수량증가
Detail 페이지 주문하기버튼 누르면 진짜 페이지 내의 상품을 장바구니에 추가하기
(Detail.js)
<button
className="btn btn-danger"
onClick={() => {
dispatch({
type: "장바구니담기",
payload: {
id: props.sticker[id].id,
name: props.sticker[realID].title,
quan: 1,
},
});
history.push("/cart");
}}
>
Order
</button>
(index.js)
function reducer(state = defaltState, action) {
if (action.type === "장바구니담기") {
let copy = [...state];
copy.push(action.payload);
return copy;
(이하생략)
}
같은 상품을 계속 주문하면 항목추가 X 수량증가 O
(index.js)
function reducer(state = defaltState, action) {
if (action.type === "장바구니담기") {
let foundIndex = state.findIndex((a) => {
return a.id === action.payload.id;
});
if (foundIndex >= 0) {
let copy = [...state];
copy[foundIndex].quan++;
return copy;
} else {
let copy = [...state];
copy.push(action.payload);
return copy;
}
(이하생략)
}
- findIndex() ? 특정 값이 array 안에 있는지 찾고 싶을때 사용하는 자바스크립트 기본함수
수량을 직접 입력할 수 있는 input을 하나 만들기
(app.js)
let [재고입력, 재고입력수정] = useState("");
<Route path="/detail/:id">
<inventoryContext.Provider value={inventory}>
<Detail
sticker={sticker}
inventory={inventory}
inventoryChange={inventoryChange}
재고입력={재고입력}
재고입력수정={재고입력수정}
/>
</inventoryContext.Provider>
</Route>
(detail.js)
<input
className="input"
onChange={(e) => {
props.재고입력수정(e.target.value);
}}
/>
<button
className="btn btn-danger"
onClick={() => {
dispatch({
type: "장바구니담기",
payload: {
id: props.sticker[id].id,
name: props.sticker[realID].title,
quan: props.재고입력,
},
});
history.push("/cart");
}}
>
Order
</button>
if (action.type === "장바구니담기") {
if (foundIndex >= 0) {
//이미 배열에 있어
let copy = [...state];
if (action.payload.quan !== "") {
//input 빈값이 아니야
copy[foundIndex].quan = action.payload.quan;
return copy;
} else {
//input 빈값이야
copy[foundIndex].quan++;
return copy;
}
} else {
//배열에 없어서 새로 push
let copy = [...state];
if (action.payload.quan !== "") {
//input 빈값이 아니야
copy.push(action.payload);
return copy;
} else {
//input 빈값이야
action.payload.quan++;
copy.push(action.payload);
return copy;
}
}
}
내가 하고자 하는 것,
input 이 빈값이면 그냥 수량 1추가,
input이 빈값이 아니면 input에 적은 수량 추가,
근데 여기서 발생한 문제
input이 초기화가 안되는 문제 ㅜㅜ
왜 이런지 좀 더 생각해봐야겠다
점점 스파게티 코딩이 되는 것 같기도,,
장바구니 항목을 삭제
(Cart.js)
<button
onClick={() => {
dispatch({
type: "삭제",
payload: {
index: i,
},
});
}}
>
X
</button>
(index.js)
function reducer(state = defaltState, action) {
if (action.type === "삭제") {
let copy = [...state];
copy.splice(action.payload.index, 1);
return copy;
}
(이하생략)
}
}