-
글쓴이글
-
2021년 2월 5일 21:22 #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.
2021년 2월 5일 22:25 #6496
codingapple키 마스터reducer라는 이름의 리듀서가 '항목추가' 액션을 받았는데 그결과로 undefined라는 state가 퉤 뱉어졌다고하네요
undefined 는 뱉지말라는 에러 같습니다
2021년 2월 7일 11:54 #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>2021년 2월 7일 20:33 #6520
codingapple키 마스터if (found >= 0) {
let copy = [...state]
copy[found].quan++
}여기 안에 state를 뱉어주는 return 뭐시기가 없는 것 같습니다
2021년 3월 31일 17:33 #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();2021년 3월 31일 21:54 #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++ 해주세요~
이런 뜻의 코드를 짜면 되겠습니다.
-
글쓴이글
- 답변은 로그인 후 가능합니다.