리액트로 이미지 업로더 구현하기

Written on July 7, 2019

파일 업로드하는걸 구현하기 어렵지 않을까? 라고 생각했었는데 의외로 아주 간단했다. <input type="file"> 만 있으면 이미 반은 성공한 것!

파일선택 input 만들기

    <input type="file" />

여기까지 하면 아래와 같이 데스크탑에서 파일을 선택하여 할 수 있는 버튼이 생성된다.

image_uploader

지금은 한개 파일만 선택할 수 있는데, <input> 태그에 multiple 속성을 추가해 주면 어려개의 파일을 동시에 선택할 수 있게된다.

선택된 파일 읽기

일반적인 input 태그에 입력된 값을 확인하는 것 처럼 onChnage 속성에 함수를 작성하여 event.target.files를 확인할 수 있으며, 이를 서버에 전송하기 위해서 state에 저장한다.

  state = { selectedFiles: null }
  fileChangedHandler = event => {
    const files = event.target.files;
    console.log(files);
    this.setState({
      selectedFiles: files
    });
  };
  render() {
    return (
      <div className="App" style={{ marginTop: "100px" }}>
        <input type="file" multiple onChange={this.fileChangedHandler} />
      </div>
    );
  }  

1개 파일을 선택하더라도 event.target.files는 배열(array) 형태이다. 콘솔로그 결과는 아래와 같다.

images_files

파일 전송하기

먼저, 전송을 trigger 할 수 있는 버튼을 만들고, 버튼에 onClick 함수를 정의해 준다. 이미지 파일을 보내기 위해서는 FormData 객체에 append(key, value) 혹은 append(key, value, filename)으로 파일값을 추가하여 전송하면 된다. files 뿐만 아니라 여러가지 key, value 쌍을 추가할 수 있으며, 전송 시, 헤더에 content-typemultipart/form-data로 명시해주어야 서버에서 적절하게 파싱을 진행할 수 있다.

onClickHandler = event => {
    const formData = new FormData();
    formData.append(
      "uploadImages",
      this.state.selectedFiles,
      this.state.selectedFiles.name
    );
    const config = {
      headers: {
        "content-type": "multipart/form-data"
      }
    };
    axios.post(`uploadAPI`, formData, config);
  };

<button onClick={this.onClickHandler}>저장하기</button>

최종 코드는 아래와 같다.

class App extends React.Component {
  state = { selectedFiles: null };
  onClickHandler = event => {
    const formData = new FormData();
    formData.append(
      "uploadImages",
      this.state.selectedFiles,
      this.state.selectedFiles.name
    );
    const config = {
      headers: {
        "content-type": "multipart/form-data"
      }
    };
    axios.post(`uploadAPI`, formData, config);
  };
  fileChangedHandler = event => {
    const files = event.target.files;
    this.setState({
      selectedFiles: files
    });
  };
  render() {
    return (
      <div className="App" style={{ marginTop: "100px" }}>
        <input type="file" multiple onChange={this.fileChangedHandler} />
        <button onClick={this.onClickHandler}>저장하기</button>
      </div>
    );
  }
}

export default App;



관련 post

multer 사용하여 이미지 업로드 구현하기

👩🏻‍💻 배우는 것을 즐기는 프론트엔드 개발자 입니다
부족한 블로그에 방문해 주셔서 감사합니다 🙇🏻‍♀️

in the process of becoming the best version of myself