-
카테고리
-
세부 분야
풀스택
-
해결 여부
해결됨
에러 질문입니다.
20.01.14 17:03 작성 조회수 339
0
TypeError: Cannot read property 'map' of undefined
at router.post (C:\Users\Desktop\react-nodebird\back\routes\post.js:59:24)
해당 라인의 59번째 줄은 아래와 같습니다.
res.json(req.files.map(v => v.filename));
이부분이 에러가 출력되는데 왜그런지 잘 모르겠습니다. 깃헙 코드랑 비교해봤는데 에러가 출력되네요.
답변을 작성해보세요.
0
0
0
0
s s
질문자2020.01.14
components/PostForm.js
import React, { useCallback, useState, useEffect, useRef } from 'react';
import { Form, Input, Button } from 'antd';
import { useSelector, useDispatch } from 'react-redux';
import { ADD_POST_REQUEST, UPLOAD_IMAGES_REQUEST } from '../reducers/post';
const PostForm = () => {
const dispatch = useDispatch();
const [text, setText] = useState('');
const { imagePaths, isAddingPost, postAdded } = useSelector(state => state.post);
const imageInput = useRef();
useEffect(() => {
if (postAdded) {
setText('');
}
}, [postAdded]);
const onSubmitForm = useCallback((e) => {
e.preventDefault();
//게시글 작성해야 글을 저장할 수 있게 해줌.
if(!text || !text.trim()) {
alert('게시글을 작성하세요.');
}
dispatch({
type: ADD_POST_REQUEST,
data: {
content: text,
},
});
}, [text]);
const onChangeText = useCallback((e) => {
setText(e.target.value);
}, []);
const onChangeImages = useCallback((e) => {
console.log(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 onClickImageUpload = useCallback(() => {
imageInput.current.click();
}, [imageInput.current]);
return (
<Form style={{ margin: '10px 0 20px' }} encType="multipart/form-data" onSubmit={onSubmitForm}>
<Input.TextArea maxLength={140} placeholder="어떤 신기한 일이 있었나요?" value={text} onChange={onChangeText} />
<div>
<input type="file" multiple hidden ref={imageInput} onChange={onChangeImages} />
<Button onClick={onClickImageUpload}>이미지 업로드</Button>
<Button type="primary" style={{ float: 'right' }} htmlType="submit" loading={isAddingPost}>짹짹</Button>
</div>
<div>
{imagePaths.map(v => (
<div key={v} style={{ display: 'inline-block' }}>
<img src={`http://localhost:3065/${v}`} style={{ width: '200px' }} alt={v} />
<div>
<Button>제거</Button>
</div>
</div>
))}
</div>
</Form>
);
};
export default PostForm;
routes/post.js
//파일 업로드
const upload = multer({
storage: multer.diskStorage({
destination(req, file, done) {
//uploads 폴더에 저장
done(null, 'uploads');
},
filename(req, file, done) {
const ext = path.extname(file.originalname);
const basename = path.basename(file.originalname, ext); //제로초.png, ext===png, basename===제로초
cb(null, basename + new Date().valueOf() + ext); //첫번째 인자: 서버 에러, 두번째 인자: 성공시
},
}),
//파일 용량 제한
limits: { fileSize: 20*1024*1024 },
});
//array('image')의 image는 PostForm.js의 imageFormData.append('image')의 이름임.
router.post('/images', upload.array('image'), (req, res) => {
console.log(req.files);
res.json(req.files.map(v => v.filename));
});
sagas/post.js
function uploadImagesAPI(formData) {
return axios.post(`/post/images`, FormData, {
withCredentials: true,
});
}
function* uploadImages(action) {
try {
const result = yield call(uploadImagesAPI, action.data);
yield put({
type: UPLOAD_IMAGES_SUCCESS,
data: result.data,
});
} catch (e) {
console.error(e);
yield put({
type: UPLOAD_IMAGES_FAILURE,
error: e,
});
}
}
function* watchUploadImages() {
yield takeLatest(UPLOAD_IMAGES_REQUEST, uploadImages);
}
reducers/post.js
case UPLOAD_IMAGES_REQUEST: {
return {
...state,
};
}
case UPLOAD_IMAGES_SUCCESS: {
return {
...state,
imagePaths: [...state.imagePaths, ...action.data],
};
}
case UPLOAD_IMAGES_FAILURE: {
return {
...state,
};
}
해당 파일 첨부합니다. 이렇게 해줬는데도 에러가 나네요. 이미지 업로드시 TypeError: Cannot read property 'map' of undefined 이러한 에러가 출력됩니다.
혹시 몰라 하나 더 첨부합니다. file의 console.log의 결과입니다.
0
조현영
지식공유자2020.01.14
req.files가 undefined인데 이 라우터에 upload.array('images') 이런 미들웨어가 붙어 있나요? 그리고 실제로 이미지 파일을 올리셨나요? 이미지 input의 name이 array('images')의 images랑 일치해야 합니다.
답변 5