• 로그인
  • 장바구니에 상품이 없습니다.

home2 게시판 React 게시판 localStorage 2 기능 후 에러문제

localStorage 2 기능 후 에러문제

7 글 보임 - 1 에서 7 까지 (총 7 중에서)
  • 글쓴이
  • #6494

    15and
    참가자

    안녕하세요 강사님

     

    장바구니 완성하기 기능까지는 에러 없이 잘 따라했는데..

    localStorage 기능 따라하다가..에러가 발생했다는 사실을 알게되었어요..

     

    에러내용은

    detail페이지에서 주문하기를 클릭하면

    이런 문구가 뜨는데 왜 그런지 가르쳐주실 수 있을까요?

    Error: Given action "항목추가", reducer "reducer" returned undefined. To ignore an action, you must explicitly return the previous state. If you want this reducer to hold no value, you can return null instead of undefined.

     

     

    #6496

    codingapple
    키 마스터

    reducer라는 이름의 리듀서가 '항목추가' 액션을 받았는데 그결과로 undefined라는 state가 퉤 뱉어졌다고하네요 

    undefined 는 뱉지말라는 에러 같습니다 

    #6505

    15and
    참가자

    if문 "항목추가" 부분을 삭제하면

    위의 에러문구는사라지고 그 외 동작은 잘되는데요..

    이부분  코드에 문제가 없는것같은데.

    왜 적용만 하면 저 에러가 뜨는지 모르겠어요..

    ( 리듀서부분부터 다시 코딩했는데도..도저히 모르겠네요..도움주실수 있을까요.)

     

    if (액션.type === "항목추가") {
    let found = state.findIndex(a => {
    return a.id === 액션.데이터.id 
    })
    if (found >= 0) {
    let copy = [...state] 
    copy[found].quan++ 
    } else {
    let copy = [...state] 
    copy.push(액션.데이터)
    return copy
    }
    } else if (액션.type === "수량증가") {
    let copy = [...state]
    copy[액션.데이터].quan++
    return copy
    } else if (액션.type === "수량감소") {
    let copy = [...state]
    copy[액션.데이터].quan-- 
    return copy
    } else {
    return state
    }

     

     

     

    (detail.js)

    function Detail(props) {
    let [alert, alert변경] = useState(true)
    let [inputData, inputData변경] = useState("")
    let [누른탭, 누른탭변경] = useState(0)
    let [스위치, 스위치변경] = useState(false)
    let { id } = useParams() 
    let history = useHistory() 
    let 찾은상품 = props.shoes.find(상품 => {
    return 상품.id == id
    })

    let 재고 = useContext(재고context) 

    useEffect(() => {

    let 타이머 = setTimeout(() => {
    alert변경(false)
    console.log("안녕")
    }, 2000) 

    return () => {
    clearTimeout(타이머)
    }
    }, []) 

    return (
    <div className="container">
    <박스>
    <제목 className="red">Detail</제목>
    </박스>

    {alert == true
    ? <div className="my-alert">
    <p>재고가얼마 남지 않았습니다.</p>
    </div>
    : null}

    <div className="row">
    <div className="col-md-6">
    <img src="https://codingapple1.github.io/shop/shoes1.jpg" width="100%" />
    </div>
    <div className="col-md-6 mt-4">
    <h4 className="pt-5">
    {찾은상품.title}
    </h4>
    <p>
    {찾은상품.content}
    </p>
    <p>
    {찾은상품.price}
    </p>

    <Info 재고={props.재고} />

    <button
    className="btn btn-danger"
    onClick={() => {
    props.재고변경([9, 11, 12])
    props.dispatch({
    type: "항목추가",
    데이터: {
    id: 찾은상품.id,
    name: 찾은상품.title,
    quan: 5
    }
    })
    history.push("/cart")
    console.log("props", props)
    }}
    >
    주문하기
    </button>

    #6520

    codingapple
    키 마스터

    if (found >= 0) {
        let copy = [...state]
        copy[found].quan++
      }

    여기 안에 state를 뱉어주는 return 뭐시기가 없는 것 같습니다 

     

    #6522

    15and
    참가자

    감사합니다~~해결됐어요.

     

    #7684

    이유진
    참가자

    어딜 손봐야할지 감이 안잡혀서 문의드립니다.

    let 초기값 = [
    // { id : 4, name : '멋진신발', quan : 2 },
    // { id : 5, name : '멋진신발2', quan : 1 }
    ]

     

    이 부분이 주석 해제 시 수량 변경 등 제대로 안먹습니다.

    도움부탁드립니다. 하단에 코드 첨부합니다.

     

    ===============

    (Detail.js)

    <div className="row">
    <div className="col-md-6">
    <img src={'https://codingapple1.github.io/shop/shoes' + (찾은상품.id + 1) + '.jpg'} width="100%" />
    </div>
    <div className="col-md-6 mt-4">
    <h4 className="pt-5">{ 찾은상품.title }</h4>
    <p>{ 찾은상품.content }</p>
    <p>{ 찾은상품.price }원</p>

    <Info 재고={props.재고} 찾은상품={찾은상품} />

    <button className="btn btn-danger" onClick={()=>{
    let copy = [...props.재고];
    copy[찾은상품.id]--;
    props.재고변경(copy);

    props.dispatch({type : '항목추가', payload : {id: 찾은상품.id, name: 찾은상품.title, quan:1} });
    history.push('/cart');

    }}>주문하기</button>
    <button className="btn btn-danger" onClick={()=>{
    history.push('/');
    }}>뒤로가기</button>
    </div>
    </div>
     

    function Info(props){
    return (
    <p>재고 : {props.재고[props.찾은상품.id]}</p>
    )
    }

    function state를props화(state){
    console.log(state);
    return {
    state : state.reducer,
    alert열렸니 : state.reducer2
    }
    }

    export default connect(state를props화)(Detail)

     

     

    (Cart.js)

    <Table responsive>
    <tr>
    <th>상품코드</th>
    <th>상품명</th>
    <th>수량</th>
    <th>변경</th>
    </tr>
    <tbody>
    {
    props.state.map((a, i)=>{
    return (
    <tr key={i}>
    <td>{ a.id }</td>
    <td>{ a.name }</td>
    <td>{ a.quan }</td>
    <td>
    <button onClick={()=>{ props.dispatch({ type: '수량증가', payload : a.id }) }}>+</button>
    <button onClick={()=>{ props.dispatch({ type: '수량감소', payload : a.id }) }}>-</button>
    </td>
    </tr>
    )
    })
    }
    </tbody>
    </Table>

    </div>
    )
    }

    function state를props화(state){
    console.log(state);
    return {
    state : state.reducer,
    alert열렸니 : state.reducer2
    }
    }

    export default connect(state를props화)(Cart)

    // export default Cart;

     

    (index.js)

    let 초기값 = [
    // { id : 4, name : '멋진신발', quan : 2 },
    // { id : 5, name : '멋진신발2', quan : 1 }
    ]

    function reducer(state = 초기값, 액션){

    if( 액션.type === '항목추가' ){

    let found = state.findIndex((a)=>{ return a.id === 액션.payload.id });

    if ( found >= 0 ){

    let copy = [...state];
    copy[found].quan++;
    return copy
     
    } else {
    let copy = [...state];
    copy.push(액션.payload);
    return copy
    }

    } else if ( 액션.type === '수량증가' ){

    let copy = [...state];
    copy[액션.payload].quan++;
    return copy
    } else if ( 액션.type === '수량감소' ){
    let copy = [...state];
    if (copy[액션.payload].quan > 0){
    copy[액션.payload].quan--;
    return copy
    } else {
    return copy
    }
    } else {
    return state
    }

    }

    let store = createStore(combineReducers({reducer, reducer2}));

    ReactDOM.render(
    <React.StrictMode>
    <BrowserRouter>
    <Provider store={store}>
    <App />
    </Provider>
    </BrowserRouter>
    </React.StrictMode>,
    document.getElementById('root')
    );

    // If you want to start measuring performance in your app, pass a function
    // to log results (for example: reportWebVitals(console.log))
    // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
    reportWebVitals();

    #7688

    codingapple
    키 마스터

    에러메세지도 있으면 첨부하면 해결이 빠릅니다 

    붙여넣어보니까 아마 quan 어쩌구가 없다는 에러가 뜨는 것 같은데 왜냐면 

     

    1. 지금 id값이 4랑 5인 상품을 첫 state로 만드셨습니다

    2. 그리고 id가 4인 상품의 수량증가 버튼을 눌러 dispatch를 날리면 payload로 4라는 정보가 전달되고, reducer 내의 if문 중에 수량증가 부분이 실행됩니다. 

    3. 그래서 reducer 내의 if문 덕분에 copy[4].quan++ 를 실행시킵니다. 그니까 state copy본의 4번째의 quan 항목을 ++ 해줄듯요  

    4. 근데 state copy본은 [ {}, {} ] 이렇게 두개의 상품밖에 없습니다. 그래서 에러가 납니다. 

     

    그래서 if문 내를 수정하면 되는데

    4번 상품의 '수량증가'를 시키면 copy[4] 번째 상품이 아니라 id가 4인 상품을 찾아서 quan++ 해주세요~

    5번 상품의 '수량증가'를 시키면 copy[5] 번째 상품이 아니라 id가 5인 상품을 찾아서 quan++ 해주세요~

    이런 뜻의 코드를 짜면 되겠습니다. 

     

     

7 글 보임 - 1 에서 7 까지 (총 7 중에서)
  • 답변은 로그인 후 가능합니다.

About

현재 월 700명 신규수강중입니다.

  (09:00~20:00) 빠른 상담은 카톡 플러스친구 코딩애플 (링크)
  admin@codingapple.com
  이용약관
ⓒ Codingapple, 강의 예제, 영상 복제 금지
top

© Codingapple, All rights reserved. 슈퍼로켓 에듀케이션 / 서울특별시 강동구 고덕로 19길 30 / 사업자등록번호 : 212-26-14752 온라인 교육학원업 / 통신판매업신고번호 : 제 2017-서울강동-0002 호 / 개인정보관리자 : 박종흠