33,000원
다른 수강생들이 자주 물어보는 질문이 궁금하신가요?
- 미해결따라하며 배우는 노드, 리액트 시리즈 - 쇼핑몰 사이트 만들기[전체 리뉴얼]
서치 관련해서 한가지 더 질문 있습니다....
지금 검색어랑 완전히 일치 해야만 검색이 되는데 일치 하는 단어가 있으면 전부 목록에 나오게 하고 싶은데 백단쪽에서 작업해야 하는건가요?
- 미해결따라하며 배우는 노드, 리액트 시리즈 - 쇼핑몰 사이트 만들기[전체 리뉴얼]
서치 질문 있습니다
백단에서 게시판 리스트 불러오는걸 get 으로 잡으니 const term 을 찾질 못하네요?..... post 로 하면 찾아내고요
- 미해결따라하며 배우는 노드, 리액트 시리즈 - 쇼핑몰 사이트 만들기[전체 리뉴얼]
에러 관련 해결
1. Error - Compiled with warnings. ./src/components/utils/FileUpload.js [1] Line 57:25: img elements must have an alt prop, either with meaningful text, or an empty string for decorative images jsx-a11y/alt-text 해결 <img style={{ minWidth: '300px', width: '300px', height: '240px' }} src={`http://localhost:5000/${image}`} alt=“” /> 추가 2. Error – 확인 버튼 미 동작 <Button type="submit" onClick={onSubmitHandler}> 확인 </Button> 으로 수정 (Basic 강의에서는 생기지 않았으나, 이번 강의에서는 이유를 몰라 여러번 코드를 확인하였습니다. 지금도 이유는 모르지만 이후에는 동작 되었습니다. 강의 감사합니다.
- 미해결따라하며 배우는 노드, 리액트 시리즈 - 쇼핑몰 사이트 만들기[전체 리뉴얼]
썜 급해요!
강의를 두세번 돌려봤는데요. uploadProductPage.js에서 맨 하단에 <Form onSubmit={submitHandler}> <Button type="submit">확인</Button> 이렇게 하셨는데요. 확인버튼에 onClick를 안해주셔도되는건가요? 실제로 테스트해보니까 저는 확인버튼을 누르면 아무 동작도 일어나지 않아요. 강사님 깃허브 코드 참고해봤는데 강사님꺼는 <Button onClick={onSubmit}>Submit</Button>; 이렇게 되어있네요. 똑같이 따라해봤는데요, 모든 값을 안넣어주고 확인을 누르면 alert는 잘 나오는데, 제대로 값을 넣어주고 확인을 넣어주면 400 에러가 나옵니다. 이 밖에도 server > models > Product.js 파일에서 continents: { type: Number, default: 1, }, 위의 코드도 이번 강의에서 찾아볼수없고, 강사님 깃허브 코드에는 있습니다. ㅠ 이번 강의에서 없는건 맞는건지 궁금합니다.. 그리고 강의 코드와 제 코드를 아무리 비교해봐도 400에러 발생지를 못찾겠는데.. 도움좀 부탁드릴께요 ㅠㅠ UploadProductPage.js import React, { useState } from "react"; import { Typography, Button, Form, Input } from "antd"; import FileUpload from "../../utils/FileUpload"; import Axios from "axios"; const { TextArea } = Input; const Continents = [ { key: 1, value: "Africa" }, { key: 2, value: "Europe" }, { key: 3, value: "North America" }, { key: 4, value: "South America" }, { key: 5, value: "Australia" }, { key: 6, value: "Australia" }, { key: 1, value: "Antarctica" }, ]; function UploadProductPage(props) { const [Title, setTitle] = useState(""); const [Description, setDescription] = useState(""); const [Price, setPrice] = useState(0); const [Continent, setContinent] = useState(1); const [Images, setImages] = useState([]); const titleChangeHandler = (event) => { setTitle(event.currentTarget.value); }; const descriptionChangeHandler = (event) => { setDescription(event.currentTarget.value); }; const priceChangeHandler = (event) => { setPrice(event.currentTarget.value); }; const continentChangeHandler = (event) => { setContinent(event.currentTarget.value); }; const updateImages = (newImages) => { setImages(newImages); }; const submitHandler = (event) => { event.preventDefault(); if (!Title || !Description || !Price || !Continent || !Images) { return alert("모든 값을 넣어주셔야 합니다."); } // 서버에 채운 값들을 request로 보낸다. const body = { // 로그인 된 사람의 ID writer: props.user.userData._id, title: Title, description: Description, price: Price, images: Images, continents: Continents, }; Axios.post("/api/product", body).then((response) => { if (response.data.success) { alert("상품 업로드에 성공 했습니다."); props.history.push("/"); } else { alert("상품 업로드에 실패 했습니다."); } }); }; return ( <div style={{ maxWidth: "700px", margin: "2rem auto" }}> <div style={{ textAlign: "center", marginBottom: "2rem" }}> <h2>여행 상품 업로드</h2> </div> <Form onSubmit={submitHandler}> {/*Drop-Zone */} <FileUpload refreshFunction={updateImages} /> <br /> <br /> <label>이름</label> <Input onChange={titleChangeHandler} value={Title} /> <br /> <br /> <labe>설명</labe> <TextArea onChange={descriptionChangeHandler} value={Description} /> <br /> <br /> <labe>가격($)</labe> <Input type="number" onChange={priceChangeHandler} value={Price} /> <br /> <br /> <select onChange={continentChangeHandler} value={Continent}> {Continents.map((item) => ( <option key={item.key} value={item.key}> {item.value} </option> ))} </select> <br /> <br /> <Button type="submit" onClick={submitHandler}> 확인 </Button> </Form> </div> ); } export default UploadProductPage; routes>product.js const express = require("express"); const router = express.Router(); const multer = require("multer"); const { Product } = require("../models/Product"); //================================= // Product //================================= var storage = multer.diskStorage({ /* 어디에 파일이 저장되는지 */ destination: function (req, file, cb) { cb(null, "uploads/"); }, /* 어떤 이름으로 파일을 저장할지 */ filename: function (req, file, cb) { cb(null, `${Date.now()}_${file.originalname}`); }, }); var upload = multer({ storage: storage }).single("file"); router.post("/image", (req, res) => { // 가져온 이미지를 저장을 해주면 된다. upload(req, res, (err) => { if (err) { return res.json({ success: false, err }); } return res.json({ success: true, filePath: res.req.file.path, fileName: res.req.file.filename, }); }); }); router.post("/", (req, res) => { // UploadProductPage.js에서 받아온 정보들을 DB에 넣어 준다. const product = new Product(req.body); product.save((err) => { if (err) return res.status(400).json({ success: false, err }); return res.status(200).json({ success: true }); }); }); module.exports = router;
- 미해결따라하며 배우는 노드, 리액트 시리즈 - 쇼핑몰 사이트 만들기[전체 리뉴얼]
문법 질문
return ( <div style={{width:'75%', margin:'3rem auto'}}> <div style={{textAlign:'center'}}> <h2>Let's travel around <Icon type="rocket"/></h2> </div> {/* filter */} {/* Check Box */} <CheckBox list={continents} handleFilters ={filters=>handleFilters(filters,"continents")} /> {/* Radio Box */} \client\src\components\views\LandingPage\LandingPage.js handleFilters ={filters=>handleFilters(filters,"continents")} 이 부분에 대한 문법이 잘 이해가 가질 않네요. 이 코드에 대해서 조금 설명을 해주실 수 있을까요?? 코드 전문은 아래와 같습니다. import React,{useEffect,useState} from 'react' import { FaCode } from "react-icons/fa"; import axios from "axios" import {Icon, Col, Card,Row } from 'antd'; import Meta from 'antd/lib/card/Meta' import ImageSlider from '../Utils/ImageSlider' import CheckBox from "./Sections/CheckBox" import continents from './Sections/Datas' function LandingPage() { const [products, setproducts] = useState([]); const [Skip, setSkip] = useState(0); const [Limit, setLimit] = useState(4); const [PostSize, setPostSize] = useState(4); const [Filters, setFilters] = useState({ continents : [], price :[] }); useEffect(() => { let body = { skip : Skip, limit : Limit } getProducts(body); }, []) const getProducts = (body)=>{ axios.post('/api/product/products', body) .then(response=>{ if(response.data.success){ if(body.loadMore){ setproducts([...products,...response.data.productInfo]); }else{ setproducts(response.data.productInfo); } console.log("response.data.PostSize" + response.data.postSize); setPostSize(response.data.postSize); }else{ alert('상품정보들을 가져오지 못했습니다. ') } }) } const renderCards = products.map((product,index)=>{ return <Col lg={6} md={8} xs={24} key={index} > <Card key={index} cover={<ImageSlider images={product.images}/>} > <Meta title={product.title} description={`$${product.price}`} /> </Card> </Col> }) const loadMoreHandler = (e)=>{ let skip = Skip + Limit; let body = { skip : skip, limit : Limit, loadMore:true } getProducts(body); setSkip(skip); } const showFilterResults = (filters)=>{ let skip = Skip + Limit; let body = { // db에서 처음부터 가져와야 하니까 skip : 0, limit : Limit, filters : filters } getProducts(body); setSkip(0); } const handleFilters= (filters,category)=>{ const newFilters = {...Filters} newFilters[category] = filters ; showFilterResults(newFilters); } return ( <div style={{width:'75%', margin:'3rem auto'}}> <div style={{textAlign:'center'}}> <h2>Let's travel around <Icon type="rocket"/></h2> </div> {/* filter */} {/* Check Box */} <CheckBox list={continents} handleFilters ={filters=>handleFilters(filters,"continents")} /> {/* Radio Box */} {/* search */} {/* Cards */} <Row gutter={[16,16]}> {renderCards} </Row> <br/> {PostSize>=Limit && <div style={{display:'flex', margin:'3rem auto', justifyContent:'center'}}> <button onClick={loadMoreHandler}>더보기</button> </div> } </div> ) } export default LandingPage 좋은 강의 감사드립니다.
- 해결됨따라하며 배우는 노드, 리액트 시리즈 - 쇼핑몰 사이트 만들기[전체 리뉴얼]
event.currentTarget.value
event.currentTarget.value 을 하신 이유에대해서 궁금합니다. event.target.value를 주로 사용해왔는데 여기서 event.currentTarget.value를 해주신 이유가 따로 있으실까요? event.currentTarget.value는 event.currentTarget // 이벤트가 바인딩된 div 요소를 반환 한다고 알고있고, 요소 구조가 복잡해질경우 사용한다고 알고있는데.. 아직 강의초반이라 어떤부분에서 사용하셧는지 확 와닿지가않는데.. 궁금합니당!
- 미해결따라하며 배우는 노드, 리액트 시리즈 - 쇼핑몰 사이트 만들기[전체 리뉴얼]
질문있습니다.
module.exports = { mongoURI: "mongodb+srv://wjdwndtlr:<password>@react-shoppingmall-kxej0.mongodb.net/test?retryWrites=true&w=majority", }; 이렇게 해줬는데요 password <> <= 이 괄호부분을 지우고 저 안에 몽고디비 패스워드를 입력하면되는건가요? 그런데 만약 깃허브같은곳에다 올릴경우 그대로 노출이될텐데.. .env작업을 안해줘도될까요?
- 미해결따라하며 배우는 노드, 리액트 시리즈 - 쇼핑몰 사이트 만들기[전체 리뉴얼]
질문입니다
파일의 정보를 state를 통해 [...state, res.data.path] 형식으로 저장하려는 로직에서 자꾸 에러가 나는데 왜 그런 것 일까요?? \client\src\components\views\Utils\Fileupload.js function Fileupload(props) { const [Images, setImages] = useState([]); const dropHandler = (files)=>{ // if you need to send file format console.log(files); let formData = new FormData(); const config = { header:{'content-type':'multipart/form-data'} } formData.append('file',files[0]); axios.post('/api/product/image',formData,config) .then(response=>{ if(response.data.success){ // to use this image info later we need to store it in state console.log(response.data); setImages([...Images, response.data.filePath]); props.refreshFunction(Images); }else{ alert('failed to save the files in server') } }) } 위 코드에서 setImages([...Images, response.data.filePath]); 가 정상적으로 동작하지 않는 것을 확인했습니다. 고쳐보려 수 차례 생각해봤는데 잘 안되네요 ㅠ 감사합니다!! git : https://github.com/JoonsongLee/q2.git
- 따라하며 배우는 노드, 리액트 시리즈 - 쇼핑몰 사이트 만들기[전체 리뉴얼]
파일 이미지 조절 관련 질문입니다.
삭제된 글입니다
- 해결됨따라하며 배우는 노드, 리액트 시리즈 - 쇼핑몰 사이트 만들기[전체 리뉴얼]
안녕하세요.
제가알기로 유데미에는 리액트를 이용한 쇼핑몰 만들기 강좌가 있지만 한국에는 한국 강사가 만든 리액트 쇼핑몰강의가 없은거로 알고있습니다. 쇼핑몰을 만들어보고싶은 욕구가 넘치던중 유데미는 아무래도 영어라 힘들겠고.. 막 찾던중에 이 강의를 알게되었네요 마치 사막의 오아시스랄까? ㅎㅎ; 감사합니다. 한번 열심히 수강해보겠습니다. 아! 저는 강사님 다른 강의들 한번도 안봤어요 ㅠ 방금 리액트를 다루는 기술 이라는 책을 다 완료하고 이 책을 복습하려고하던중 이 강의를 만나게되어서 이 강의를 한번 완료후에 리액트를 다루는 기술과, 이 강의에서 배운 내용을 짬뽕시켜봐야겠네요 ㅋㅋ 배포하신 영상은 유튜브 가면 있을까요??
- 미해결따라하며 배우는 노드, 리액트 시리즈 - 쇼핑몰 사이트 만들기[전체 리뉴얼]
html 파일 저만 안보이나요???
클릭해도 안나오네요 ㅠㅠ 혹시 재 업로드 해주실 수 있을까요? 감사합니다.
- 미해결따라하며 배우는 노드, 리액트 시리즈 - 쇼핑몰 사이트 만들기[전체 리뉴얼]
일빠로 질문?(제안) 합니다
존안님 안녕하세요. 존안님의 열혈팬 andrew lee입니다 ㅋㅋㅋ 유료강의 소식을 듣고 바로 결제를 해버렸네유 저는 이제 기본강의랑 유투브 듣고 이제 다 정리하고 코드레벨에서 전체적인 분석을 마쳤는데요, 정말 너무 컨텐츠도 좋고 개발자로서 발돋움하는데 최적의 컨테츠를 제안하시는 것 같습니다. 다만 조금 아쉬운 점이 있는데요... 마무리에 대한 내용을 보강해주실 수 있으신지요?? 다 만들고나서 로컬단에서만 돌려봤지 실제 서비스 수준의 배포를 해보는 귀한 경험을 해보고 싶은데 쉬운 일이 아니네요 ㅠ 초심자가 경험하기엔 진입장벽이 조금 높고, 한번 가이드 영상을 남겨주신다면 그 후에 다른 서비스를 이용하는 거는 쉬울 것 같은데 항상 처음이 어렵습니다... 그간에 답변을 남겨주셔서 좀 도전해봤지만 ec2안에 nginx를 어떻게 올려야하는지에 대해서 차근차근 설명해주는 영상이 있었으면 정말!! 좋겠어요 ㅠㅠ 강의가 짧아도 상관이 없고 존안님의 차분한 설명과 함께 배포도 함께 배워보고 싶네요. 아직 이 강의를 들어보지도 못했지만 이 말을 드리고 싶어서 결제부터하고ㅋㅋ.. 질문을 드렸습니다. 좋은 강의 올려주셔서 감사해요!