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;
  } 
(이하생략)
  }
}