10 글 보임 - 1 에서 10 까지 (총 10 중에서)
-
글쓴이글
-
2022년 9월 2일 15:13 #45078
김지우참가자답변으로 항상 큰 도움 주셔서 감사합니다. 다름이 아니라 오늘도 선생님께 질문이 있어서 찾아왔습니다. 장바구니 기능에서 redux toolkit으로 관리중인 state.cart 를 db로 한번 저장해보려고 합니다. 그래서 cartState 라는 collection 하나 만들었고 server.js 에서는 우선 이렇게 코드를 추가했습니다. app.post('/cart', function(요청, 응답){ 응답.send('전송완료'); db.collection('cartState').insertOne(state.cart, function(){ console.log('저장완료') }); }); app.put('/cart', function(요청, 응답){ db.collection('cartState').updateOne(state.cart, function(){ console.log('수정완료') 응답.redirect('/cart') }); }); 그리고 Detail.js 에서 버튼을 누르면 axios 로 state.cart 를 이렇게 post 요청하고 <button className = "buttonGreen" style={{width:'85px'}} onClick={() => { 찾은상품개수변경(()=>{ 찾은상품.quan --; }) dispatch( addItem({ id: 찾은상품.id, name: 찾은상품.title, quan: 1}) ); navigate("/cart"); axios.post("/cart").then((결과) => console.log(결과)).catch(() => console.log("전송 실패!")) }} > 장바구니 </button> Cart.js 에서 +1, -1 버튼을 누르면 axios 로 state.cart 를 이렇게 put 요청했습니다 <button className="buttonOrange" role="button" onClick={ ()=>{dispatch(addCount(a.id)) axios.put("/cart").then((결과) => console.log(결과)).catch(() => console.log("전송 실패!"))}}> +1</button> <button className="buttonGreen" role="button" onClick={ ()=>{dispatch(subCount(a.id)) axios.put("/cart").then((결과) => console.log(결과)).catch(() => console.log("전송 실패!"))}}> -1</button> 그런데 여기서 아래처럼 에러가 발생합니다 detail.js 의 장바구니 추가버튼은 브라우저 콘솔에서 전송완료라고 뜨는데, (다시 확인해보니 cartState collection 에 추가되지 않고 아예 비어있네요) cart.js 의 +1, -1 버튼은 콘솔에서 전송 실패가 뜹니다 (콘솔 사진 첨부했습니다).
그리고 vsc 터미널에서는 아래와 같은 에러가 뜹니다. state 가 정의되지 않았다는 게 무슨 말일까요? server.js 까지 state가 전달 되지 않는 것 같은데 state 를 어떻게 전달해야 할지 잘 이해가 가지 않습니다ㅠㅠ (애초에 그럼 detail.js 의 장바구니 버튼은 왜 전송완료라고 뜨는걸까요?) ReferenceError: state is not defined at /Users/ziuss/Documents/GitHub/hochony1/server.js:66:40 at Layer.handle [as handle_request] (/Users/ziuss/Documents/GitHub/hochony1/node_modules/express/lib/router/layer.js:95:5) at next (/Users/ziuss/Documents/GitHub/hochony1/node_modules/express/lib/router/route.js:144:13) at Route.dispatch (/Users/ziuss/Documents/GitHub/hochony1/node_modules/express/lib/router/route.js:114:3) at Layer.handle [as handle_request] (/Users/ziuss/Documents/GitHub/hochony1/node_modules/express/lib/router/layer.js:95:5) at /Users/ziuss/Documents/GitHub/hochony1/node_modules/express/lib/router/index.js:284:15 at Function.process_params (/Users/ziuss/Documents/GitHub/hochony1/node_modules/express/lib/router/index.js:346:12) at next (/Users/ziuss/Documents/GitHub/hochony1/node_modules/express/lib/router/index.js:280:10) at serveStatic (/Users/ziuss/Documents/GitHub/hochony1/node_modules/serve-static/index.js:75:16) at Layer.handle [as handle_request] (/Users/ziuss/Documents/GitHub/hochony1/node_modules/express/lib/router/layer.js:95:5)
2022년 9월 2일 22:48 #45134
codingapple키 마스터post요청으로 서버에 데이터를 보내야 서버는 데이터수신이 가능합니다 axios.post('/경로', 보낼데이터) 이럽시다 그럼 서버에선 요청.body.어쩌구 하면 데이터 나옵니다
2022년 9월 3일 15:44 #45185
김지우참가자아아 그런것이었군요. 그래서 아래처럼 post 요청을 했습니다. axios.post("/cart", state.cart).then((결과) => console.log(결과)).catch(() => console.log("전송 실패!")) put 요청도 똑같을 것 같아서 아래처럼 보낼 데이터를 넣었습니다. <button className="buttonOrange" role="button" onClick={ ()=>{dispatch(addCount(a.id)) axios.put("/cart", state.cart).then((결과) => console.log(결과)).catch(() => console.log("전송 실패!"))}}> +1</button> 그런데 server.js 가 잘 감이 오질 않아서 여러 시도를 해봤습니다.
app.post('/cart', function(요청, 응답){ 응답.send('전송완료'); db.collection('cartState').insertOne(요청.body.state.cart, function(){ console.log('저장완료') }); });
app.put('/cart', function(요청, 응답){ db.collection('cartState').updateOne(요청.body.state.cart, function(){ console.log('수정완료') 응답.redirect('/cart') }); }); 저 위에 요청.body.state.cart 를 넣은 부분에 그냥 state.cart 를 넣으면 state 가 정의되지 않았다고 떠서 이렇게 넣은 것인데 TypeError: Cannot read properties of undefined (reading 'cart') 이런 에러가 뜹니다. 그리고 state.cart 초기값이 원래 빈 배열이니 요청.body.state.cart[0] 이렇게 넣어야 하는 건가 싶었는데도 에러가 뜨더군요 state.cart 가 여기서 요청.body 인 것인가 싶어 요청.body 나 요청.body[0] 도 마찬가지 입니다. must be valid Javascript Object 이런 에러가 뜹니다. 여기에 무엇을 넣어야 하는 걸까요? 애초에 제가 state.cart 를 잘못 넣은 것일까요?
2022년 9월 3일 23:12 #45216
codingapple키 마스터리액트에서 state.cart부터 출력해보고 잘 있으면 서버에서 요청.body도 똑같이 나오나 출력해봅시다
2022년 9월 5일 22:25 #45471
김지우참가자app.post('/cart', function(요청, 응답){ 응답.send('전송완료'); db.collection('cartState').insertOne(요청.body, function(){ console.log(요청.body); console.log('저장완료'); }); });
app.put('/cart', function(요청, 응답){ 응답.send('전송완료'); db.collection('cartState').updateOne(요청.body, function(){ console.log(요청.body); console.log('수정완료'); }); }); 제가 put 요청에 응답.send() 를 안해줘서 오류가 난 것 같습니다. 이제 브라우저 콘솔에서도 {data: "전송완료", status: 200, statusText: "OK", headers: Object, config: Object, …} 이런게 post, put 요청 할 때 모두 잘 뜨네요. react 에서도 state.cart 가 잘 뜹니다. 하지만 문제는 post 요청을 할 때 state의 초기값인 [] 가 전송된다는 게 문제인 것 같습니다. (리액트에선 장바구니 화면에 추가되면 빈 어레이를 뱉고 + 를 누르면 그제서야 Array (1) 0 {_id: 0, id: 0, name: "This is my seat", quan: 1} 이렇게 1개로 콘솔에 띄워줍니다. 아래는 빈 어레이가 뜨는 detail.js axios.post("/cart", state.cart).then((결과) => console.log(결과)).catch(() => console.log(state.cart)) 이건 quan: 1개씩 늦게 뜨는 cart.js 코드입니다. <button className="buttonOrange" role="button" onClick={ ()=>{dispatch(addCount(a.id)) axios.put("/cart", state.cart).then((결과) => console.log(결과)).catch(() => console.log(state.cart))}}> +1</button> ) 그래서 아래처럼 서버에서는 새 _id 를 붙여주긴 하지만 빈 어레이다 보니 collection 에 저장을 해주진 않네요. 실제로 몽고디비 가보면 컬렉션이 비어있습니다. [ _id: new ObjectId("6315f4034e0e2c4f608107af") ] 저장완료 그리고 아래 이 에러는 put요청을 할때, 즉 + 버튼을 누를 때 일어납니다. MongoInvalidArgumentError: Document must be a valid JavaScript object
2022년 9월 6일 09:46 #45485
codingapple키 마스터dispatch 완료되기 전에 ajax요청되어서 그런가봅니다 addCount 함수 안에서 state변경 후 ajax 요청해봅시다
2022년 9월 6일 15:14 #45535
김지우참가자말씀하신대로 아래와 같이 store.js 에서 함수 안에서 state 변경 후 ajax 요청을 해봤습니다. 그랬더니 post 요청은 새로운 _id 를 배정해서 collection에 추가를 해 주지만 아직도 빈 어레이를 넣는 것 같습니다. 그리고 여전히 put 요청은 MongoInvalidArgumentError: Document must be a valid JavaScript object 에러를 띄웁니다. 제가 ajax 요청을 잘못 하고 있는 것일까요?? let cart = createSlice({ // state 생성 + useState 같은 거임, state + reducer 를 slice 라고 부름 name : 'cart', // 함수 형태의 reducer 라 깔끔하고 원래 복사본 만드는 걸 자동으로 해줘서 원본 바꾸는 형태로 사용 가능 initialState : [], reducers : { // 변수로 초기값 만들고 reducer 안에 넣기 그리고 state 수정하는 법도 작성 addItem(state, action) { let found = state.findIndex((a)=>{return a.id === action.payload}) if (found >= 0){ state[found].quan++; } else { state.push(action.payload); } axios.post("/cart", state.cart).then((결과) => console.log(결과)).catch(() => console.log(state.cart)); }, addCount (state, action) { let found = state.findIndex((a)=>{return a.id === action.payload}) state[found].quan++; axios.put("/cart", state.cart).then((결과) => console.log(결과)).catch(() => console.log(state.cart)); }, subCount(state, action) { let found = state.findIndex((a)=>{return a.id === action.payload}) if (state[found].quan > 1) { state[found].quan--; } else if (state[found].quan <= 1) { delete(state[found]); } axios.put("/cart", state.cart).then((결과) => console.log(결과)).catch(() => console.log(state.cart)); } } });
2022년 9월 6일 20:19 #45578
codingapple키 마스터state.push(action.payload); 하는거 보니까 state는 array자료같은데 axios.post("/cart", state.cart 에선 state를 object처럼 쓰고있군요
2022년 9월 6일 22:05 #45604
김지우참가자바보같이 복붙해버렸네요...ㅠㅠ 선생님 말씀대로 state는 array 자료가 맞습니다. axios.post("/cart", state 로 바꾸고, 서버에서는 db.collection('cartState').insertMany(요청.body, function(){ 이렇게 하니 잘 옮겨 집니다. 그런데 문제점은 뒤로가기를 눌러서 다른 품목 하나를 더 추가해서 state를 [{제품 1번의 정보}, {제품 2번의 정보}] 이렇게 만들어도 collection은 최초 제품 1개 밖에 업로드 하지 않네요.. 아마 이미 제품 1번이 이미 있어서 1번과 2번을 한꺼번에 넣는 것은 중복이라 안되는 것 같습니다. 제품 1번이 있으면 다시 장바구니에 넣어도 안되듯이 말입니다. 그리고 제가 updateOne 도 전혀 잘못 이해하고 있었습니다. state 전체를 모두 한번에 쉽게 업데이트 할 수 있을 것 같았는데 MongoDB 메뉴얼을 보고서 이걸로 장바구니 state 를 수정하는 게 매우 복잡할 것 같다는 생각이 들었습니다. 다시 한번 고민해보고 너무 불필요한 코드가 많아질 것 같다면 다시 localStorage 를 활용하는 방법으로 가보겠습니다! 이번에도 친절한 답변 감사합니다 선생님!
-
글쓴이글
10 글 보임 - 1 에서 10 까지 (총 10 중에서)
- 답변은 로그인 후 가능합니다.