728x90
다음은 클릭이벤트로 주었던 상세페이지와 삭제,upload 기능
상세보기페이지에서 삭제기능은 함께 추가되어있다.
async function getProduct(id){
const response = await axios.get(`${API_URL}/product/${id}`);
return response.data; // id값 하나만 받아오기위해 id를 이용해 값을 호출해온다.
// 서버에서는 findOne함수로 id값이 있는 1개의 값만 돌려준다.
}
const ProductPage = () => {
const navigate = useNavigate(); // 네비게이션을 사용하기위해 함수 생성
const { id } = useParams(); // 객체언어 Params로 클릭할때 넘어온 id값을 가져올 수 있다.
// id값은 App.js에서 Route에서 product/:id 로 선언되어 있기에 params로 get에있는 값을 가져옴
const [state] = useAsync(()=>getProduct(id),[id]); // Params가 객체언어이기때문에 { } 로 받아왔지만 변수로 사용해야한다.
const { loading, data:product, error } = state;
const productdel = () => {
axios.delete(`${API_URL}/product/${id}`) // delete 요청을 보냄(서버에서 product로 요청받고 {id}값을 확인해 해당데이터를 지워줌)
.then(result=>{
console.log('삭제되었습니다.');
navigate("/"); // useNavigate를 사용해 삭제 후 제일처음 App.js로 이동하도록함
})
.catch(e=>{
console.log(e);
})
}
if(loading) return <div>로딩중입니다.......</div>;
if(error) return <div>에러가 발생했습니다.</div>;
if(!product) return null;
return (
<div className='inner'>
<div id="image-box">
<img src={product.imageUrl} alt=""/>
</div>
<div id="profile-box">
<ul>
<li>
<div>
<img src="/images/icons/avatar.png" alt=""/>
<span>{product.seller}</span>
</div>
</li>
<li>
{product.name}
</li>
<li>
가격 {product.price}원
</li>
<li>등록일 : 어제빰</li>
<li>{product.desciption} </li>
</ul>
</div>
<div>
<span onClick={productdel}>삭제하기</span>
{/* 삭제 함수 호출 */}
</div>
</div>
);
};
const UploadPage = (props) => {
const navigate = useNavigate();
//이미지 경로 상태관리 추가
const [ imageUrl, setImageUrl ] = useState(null);
//이미리 처리함수
const onChangeImage = (info)=>{
//파일이 업로드 중일때
//status 는 상태를 나타냄. uploading는 로딩이되는중이고
//done이 되면 업로드가 완료되어서 값을 사용할 수 있음.
if(info.file.status === "uploading"){
return;
}
//파일이 업로드 완료되었을때
if(info.file.status === "done"){
const response = info.file.response;
const imageUrl = response.imageUrl;
//받은 이미지경로를 imageUrl에 넣어줌
setImageUrl(imageUrl);
}
console.log(info.file);
}
const onSubmit = (values) => {
//서버로 데이터 전송하기
axios.post(`${API_URL}/products`,{
name:values.name,
seller:values.seller,
price:values.price,
imageUrl:imageUrl,
desciption:values.desciption // values로 받아와서 .컬럼명으로 업데이트해준다.
}).then((result) => {
console.log(result);
navigate("/");
})
.catch(e=>{
console.log(e)
})
}
return (
// form은 antdisign에서 가져옴.
<div id="upload-container" className='inner'>
{/* onFinish = submit */}
<Form name="productUpload" onFinish={onSubmit}>
<Form.Item name="imgUpload"
label={<div className='upload-label'>상품사진</div>}
>
<Upload name="image" action={`${API_URL}/image`}
listType="picture" showUploadList={false} onChange={onChangeImage}>
{/* 업로드 이미지가 있으면 이미지를 나타내고 업로드 이미지가 없으면
회색배경에 업로드 아이콘이 나타나도록... */}
{ imageUrl ? <img src={imageUrl}
alt="" width="200px" height="200px" /> :
(<div id="upload-img-placeholder">
<img src="images/icons/camera.png" alt=""/>
<span>이미지를 업로드 해주세요.</span>
</div>)
}
</Upload>
</Form.Item>
<Divider/>
<Form.Item name="seller"
label={<div className='upload-label'>판매자명</div>}>
<Input className="nameUpload" size="large"
placeholder="판매자이름을 입력하세요"/>
</Form.Item>
<Divider/>
<Form.Item name="name"
label={<div className="upload-label">상품이름</div>}>
<Input
className='upload-name'
size='large'
placeholder='상품이름을 입력해주세요'
/>
</Form.Item>
<Divider/>
<Form.Item name="price"
label={<div className="upload-label">상품가격</div>}>
<InputNumber defaultValue={0} size="large" />
</Form.Item>
<Divider/>
<Form.Item name="desciption"
label={<div className='upload-label'>상품소개</div>}
>
<Input.TextArea
size='large'
id="product-desciption"
maxLength={300}
placeholder="상품 소개를 적어주세요"
/>
</Form.Item>
<Form.Item>
<Button id="submit-button" size="large" htmlType='submit'>
상품등록하기
</Button>
</Form.Item>
</Form>
</div>
);
};
서버로 업로드를 한다. 밑의 form은 ant design에서 가져와 name으로 값을 받아서 보내주고 위의 함수에서 값이 모두 처리된다.
728x90
'프론트앤드 수업' 카테고리의 다른 글
[React] Sqlite DB사용, 간단한 웹페이지 만들기_5 (0) | 2022.07.05 |
---|---|
[React] Sqlite DB사용, 간단한 웹페이지 만들기_4 (0) | 2022.07.05 |
[React] Sqlite DB사용, 간단한 웹페이지 만들기_2 (0) | 2022.07.05 |
[React] Sqlite DB사용, 간단한 웹페이지 만들기_1 (0) | 2022.07.05 |
[React] Constext 활용 (0) | 2022.06.29 |