작성
·
613
답변 2
1
image 해봤다가 안되면 images 해보고, 안되면 Image 해보고 이런 식으로 하는 게 아니라 명확한 이유가 있어야 합니다. 그 논리적 사고를 하면서 프로그램을 제작을 하셔야 하고요.
0
console.log(imageInput);을 하면 위와 같이 나옵니다!
import { Form, Input, Button } from "antd";
import { useCallback, useRef, useEffect, useState } from "react";
import { useDispatch, useSelector } from "react-redux";
import {
ADD_POST_REQUEST,
UPLOAD_IMAGES_REQUEST,
REMOVE_IMAGE,
} from "../reducers/post";
import useInput from "./hooks/useInput";
import { backUrl } from "./config/config";
const PostForm = () => {
const { imagePaths, addPostDone } = useSelector((state) => state.post);
const dispatch = useDispatch();
const [text, onChangeText, setText] = useInput("");
useEffect(() => {
if (addPostDone) {
setText("");
}
}, [addPostDone]);
const onSubmit = useCallback(() => {
if (!text || !text.trim()) {
return alert("게시글을 작성하세요.");
}
const formData = new FormData();
imagePaths.forEach((p) => {
formData.append("Image", p);
});
formData.append("content", text);
return dispatch({
type: ADD_POST_REQUEST,
data: formData,
});
}, [text, imagePaths]);
const imageInput = useRef();
console.log(imageInput);
const onClickImageUpload = useCallback(() => {
imageInput.current.click();
}, [imageInput.current]);
const onChangeImages = useCallback((e) => {
console.log("images", e.target.files);
const imageFormData = new FormData();
[].forEach.call(e.target.files, (f) => {
imageFormData.append("image", f);
});
dispatch({
type: UPLOAD_IMAGES_REQUEST,
data: imageFormData,
});
}, []);
const onRemoveImage = useCallback(
(index) => () => {
dispatch({
type: REMOVE_IMAGE,
data: index,
});
},
[]
);
return (
<Form
style={{ margin: "10px 0 20px" }}
encType="multipart/form-data"
onFinish={onSubmit}
>
<Input.TextArea
value={text}
onChange={onChangeText}
maxLength={140}
placeholder="어떤 신기한 일이 있었나요?"
/>
<div>
<input
type="file"
name="image"
multiple
hidden
ref={imageInput}
onChange={onChangeImages}
/>
<Button onClick={onClickImageUpload}>이미지 업로드</Button>
<Button type="primary" style={{ float: "right" }} htmlType="submit">
짹짹
</Button>
</div>
<div>
{imagePaths.map((v, i) => (
<div key={v} style={{ display: "inline-block" }}>
<img
src={v.replace(/\/thumb\//, "/original/")}
style={{ width: "200px" }}
alt={v}
/>
<div>
<Button onClick={onRemoveImage(i)}>제거</Button>
</div>
</div>
))}
</div>
</Form>
);
};
export default PostForm;
그러면 addPostRequest할 때
formData.append("Image", p);
이게 맞나요? 소문자여야 하는 거 아닌가요?
formData.append("image", p);
데이터 문제가 발생했을 때는 백엔드부터 문제파악하는 겁니다. 백엔드에 문제가 없으면 프론트에서 백엔드로 잘못된 데이터를 전달해줬을 것이고요. 웹 서비스의 기본 프로세스를 이해하지 못하면 앞으로 에러 해결에 매우 어려움을 겪으실 겁니다.
const DataTypes = require("sequelize");
const { Model } = DataTypes;
module.exports = class Image extends Model {
static init(sequelize) {
return super.init(
{
// id가 기본적으로 들어있다..
src: {
type: DataTypes.STRING(200),
allowNull: false,
},
},
{
modelName: "Image",
tableName: "images",
charset: "utf8",
collate: "utf8_general_ci",
sequelize,
}
);
}
static associate(db) {
db.Image.belongsTo(db.Post);
}
};
router.post("/", isLoggedIn, upload.none(), async (req, res, next) => {
// POST /post
try {
const hashtags = req.body.content.match(/#[^\s#]+/g);
const post = await Post.create({
content: req.body.content,
UserId: req.user.id,
});
if (hashtags) {
const result = await Promise.all(
hashtags.map((tag) =>
Hashtag.findOrCreate({
where: { name: tag.slice(1).toLowerCase() },
})
)
); // [[노드, true], [리액트, true]]
await post.addHashtags(result.map((v) => v[0]));
}
if (req.body.images) {
if (Array.isArray(req.body.images)) {
// 이미지를 여러 개 올리면 image: [제로초.png, 부기초.png]
const images = await Promise.all(
req.body.images.map((image) => Image.create({ src: image }))
);
await post.addImages(images);
} else {
// 이미지를 하나만 올리면 image: 제로초.png
const image = await Image.create({ src: req.body.images });
await post.addImages(image);
}
}
const fullPost = await Post.findOne({
where: { id: post.id },
include: [
{
model: Image,
},
{
model: Comment,
include: [
{
model: User, // 댓글 작성자
attributes: ["id", "nickname"],
},
],
},
{
model: User, // 게시글 작성자
attributes: ["id", "nickname"],
},
{
model: User, // 좋아요 누른 사람
as: "Likers",
attributes: ["id"],
},
],
});
res.status(201).json(fullPost);
} catch (error) {
console.error(error);
next(error);
}
});
router.post("/images", isLoggedIn, upload.array("image"), (req, res, next) => {
// POST /post/images
console.log(req.files);
res.json(req.files.map((v) => v.location));
});
이미지에는 데이터가 안들어오네요 ㅠㅠ
왜 req.body.images로 하셨나요?
append('image')면 req.body도 image입니다.
https://github.com/ZeroCho/react-nodebird/blob/master/ch7/back/routes/post.js#L48
req.body.image로 하니까 500에러가 떠서 images를 하니까 이미지는 안올라가도 게시물은 올라가져서 images로 했었습니다.
다른곳이 문제인거 같습니다 ㅠㅠ
그 500 에러가 뭐였나요? image에서 images로 바꾸게 된 논리가 무엇이었나요? 프로그래밍 시에는 논리와 이유가 있어야 합니다. 그걸 모르고 하는 건 그냥 타자 연습입니다.
해결 했습니다. 문제는 어떤분 댓글 보고 혹시나 했는데 이미지 파일 이름에 영어만 넣으니까 올라가졌습니다.
한글이나 숫자로 된 이미지 파일 이름들은 실험결과 안올라가졌는데 해결방법을 찾아봐야겠습니다
네 이미지파일을 잘들어 옵니다!