강의

멘토링

커뮤니티

Cộng đồng Hỏi & Đáp của Inflearn

Hình ảnh hồ sơ của ssp57460900
ssp57460900

câu hỏi đã được viết

Tạo NodeBird SNS bằng React

6-9. Tải lên hình ảnh với multer

에러 질문입니다.

Đã giải quyết

Viết

·

547

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));

이부분이 에러가 출력되는데 왜그런지 잘 모르겠습니다. 깃헙 코드랑 비교해봤는데 에러가 출력되네요.

reactjavascript

Câu trả lời 5

0

s s님의 프로필 이미지
s s
Người đặt câu hỏi

답변감사합니다 갓로초님

0

s s님의 프로필 이미지
s s
Người đặt câu hỏi

undefined요

0

zerocho님의 프로필 이미지
zerocho
Người chia sẻ kiến thức

노드 서버쪽에서 console.log(req.files)는 결과가 어떤가요?

0

s s님의 프로필 이미지
s s
Người đặt câu hỏi

components/PostForm.js

import React, { useCallbackuseStateuseEffectuseRef } from 'react';
import { FormInputButton } from 'antd';
import { useSelectoruseDispatch } from 'react-redux';
import { ADD_POST_REQUESTUPLOAD_IMAGES_REQUEST } from '../reducers/post';

const PostForm = () => {
  const dispatch = useDispatch();
  const [textsetText] = useState('');
  const { imagePathsisAddingPostpostAdded } = 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(reqfiledone) {
         //uploads 폴더에 저장
         done(null'uploads');
       },
       filename(reqfiledone) {
         const ext = path.extname(file.originalname);
         const basename = path.basename(file.originalnameext); //제로초.png, ext===png, basename===제로초
         cb(nullbasename + new Date().valueOf() + ext); //첫번째 인자: 서버 에러, 두번째 인자: 성공시
        },
    }),
    //파일 용량 제한
    limits: { fileSize: 20*1024*1024 },
});
//array('image')의 image는 PostForm.js의 imageFormData.append('image')의 이름임.
router.post('/images'upload.array('image'), (reqres=> {
  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(uploadImagesAPIaction.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_REQUESTuploadImages);
}

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

zerocho님의 프로필 이미지
zerocho
Người chia sẻ kiến thức

req.files가 undefined인데 이 라우터에 upload.array('images') 이런 미들웨어가 붙어 있나요? 그리고 실제로 이미지 파일을 올리셨나요? 이미지 input의 name이 array('images')의 images랑 일치해야 합니다.

Hình ảnh hồ sơ của ssp57460900
ssp57460900

câu hỏi đã được viết

Đặt câu hỏi