inflearn logo
강의

강의

N
챌린지

챌린지

멘토링

멘토링

N
클립

클립

로드맵

로드맵

지식공유

React로 NodeBird SNS 만들기

6-9. multer로 이미지 업로드 받기

에러 질문입니다.

해결된 질문

564

s s

작성한 질문수 22

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

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

react javascript

답변 5

0

s s

답변감사합니다 갓로초님

0

s s

undefined요

0

제로초(조현영)

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

0

s s

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

제로초(조현영)

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

next 10 이상에서는 redux dev tool 구동이 안되나요?

0

272

1

세션 갱신 문의 건

0

483

7

배포 진행 후 Highlight updates components render 표시

0

445

1

똑같은 기능을 하는 테이블

0

448

4

관계형

0

312

2

프론트 서버를 이용하지 않는경우

1

299

3

인피니트 스크롤링 사용시 오류

0

278

0

계속 이런에러가 떠서 해결하기는 했는데 어떤 의미인지 모르겠습니다.

0

434

2

req.user가 언제 생성되나요??

0

330

2

Cannot read property 'id' of null 에러

0

333

1

리트윗한 게시글 불러오는 sequelize

0

252

1

result.data에서 images인 이유

0

281

2

takeLatest에 대한 질문입니다.

1

342

2

프론트에서 express를 사용하지 않을때 동적라우팅

0

501

6

getInitialProps가 클라이언트에서 수행되는 이유?

0

258

1

리로드하면 팔로우 언팔로우 값이 초기화 되는 문제입니다.

0

445

2

스타일드 컴포넌트와 className을 통한 스타일 적용의 차이에 대해 궁금합니다

0

585

2

할인 쿠폰 사용이 안되는되요 (848-f9af83f183e3)

0

365

1

nodejs mvc 패턴

0

975

4

사용하고 보니, 람다 구성이 궁금합니다!

0

266

1

제로초님

0

445

1

새로고침 로그인 풀림 문제.

0

247

1

안녕하세요. 강의 너무 감사합니다

0

157

1

제로초님

0

170

1