고객 추가 양식(Form) 구현 및 이벤트 핸들링

Tin9oo·2023년 12월 9일
0

CustomerAdd.js

components에 CustomerAdd.js를 추가한다.

서버와의 통신 목적 라이브러리인 axios를 설치한다.

cd client
npm install --save axios

나는 npm 설치에 오류가 발생해서 yarn으로 설치했다.

yarn add axios

파일 작성

필요 라이브러리 불러오기

import React from "react";
import axios from 'axios';

컴포넌트 정의

class CustomerAdd extends React.Component {}

생성자

constructor(props) {
  super(props);
  this.state = {
    file: null,
    userName: '',
    birthday: '',
    gender: '',
    job: '',
    fileName: ''
  }
}

render()

  • form
    고객 추가 버튼을 누르면 onSubmit에 설정된 this.handleFormSubmit함수의 동작을 실행한다.

  • input type="file
    type의 유형으로 설정되며, name의 이름으로 전달받은 곳(서버)에서 사용된다.
    file은 파일의 실제 정보, value는 파일의 이름을 저장한다.
    onChange는 사용자가 파일을 업로드 해서 보낼 준비가 되었을 때 처리 결과를 사용자에게 보여주기 위한 함수를 불러온다.
    버튼을 클릭하면 onSubmit이 실행된다.

render() {
  return (
    <form onSubmit={this.handleFormSubmit}>
    <h1>고객 추가</h1>
프로필 이미지: <input type="file" name="file" file={this.state.file} value={this.state.fileName} onChange={this.handleFileChange}/><br/>
  이름: <input type="text" name="userName" value={this.state.userName} onChange={this.handleValueChange}/><br/>
    생년월일: <input type="text" name="birthday" value={this.state.birthday} onChange={this.handleValueChange}/><br/>
      성별: <input type="text" name="gender" value={this.state.gender} onChange={this.handleValueChange}/><br/>
        직업: <input type="text" name="job" value={this.state.job} onChange={this.handleValueChange}/><br/>
          <button type="submit">추가하기</button>
</form>
)
}

외부에서 사용될것이기 때문에 export 해줘야한다.

export default CustomerAdd;

필요 함수 정의

input 태그가 있으면 값 변경 시 상태 변화를 감지하기 위한 onChange 함수가 만들어져 있어야 한다.

경로와 넘길 데이터를 지정하고 파일을 전송하기 위한 헤더를 설정해줘야한다.

addCustomer = () => {
  const url = '/api/customers';
  const formData = new FormData();
  formData.append('image', this.state.file);
  formData.append('name', this.state.userName);
  formData.append('birthday', this.state.birthday);
  formData.append('gender', this.state.gender);
  formData.append('job', this.state.job);
  const config = {
    headers: {
      'content-type': 'multipart/form-data'
    }
  }
  return axios.post(url, formData, config);
}

handleFormSubmit

이벤트를 내부적으로 전달받는다.
데이터가 서버로 전달됨에 있어 오류가 발생하지 않도록 prevent설정을 한다.

handleFormSubmit = (e) => {
  e.preventDefault();
  this.addCustomer()
    .then((response) => {
    console.log(response.data);
  })
}

handleFileChange

e.target은 이벤트가 발생한 input 값을 의미한다.
아래 코드는 업로드된 여러 파일 중 첫번째 파일을 다룬다.

handleFileChange = (e) => {
  this.setState({
    file: e.target.files[0],
    fileName: e.target.value
  })
}

handleValueChange

상태를 갱신하는 코드다.
그런데 궁금한게, 수정된 상태에 대해서만 update 하는건가?

handleValueChange =(e) => {
  let nextState = {};
  nextState[e.target.name] = e.target.value;
  this.setState(nextState);
}

App.js

작업한 CustomerAdd.js를 화면에 출력하기 위해 App.js를 수정하겠다.

아래 명령어로 불러온다.

import CustomerAdd from './components/CustomerAdd';

이제 render() 부분만 수정해주면 된다.

기존 출력 부분 아래에 추가하겠다.
div 태그로 기존 출력부를 한번 감싸겠다.
그리고 아래에 ComponentAdd 컴포넌트를 추가한다.

<div>
  <Paper sx={{width: '100%', marginTop:theme.spacing(3), overflowX: "auto"}}>
    기존 출력부
      </Paper>
    <CustomerAdd/>
      </div>

반영 안됨?

재시작하세요.
axios라이브러리에서 post를 불러오는게 아니라. axios를 불러오고 코드 상에서 axios.post 이런식으로 사용해야함.

사진 선택 시 먹통

파일 핸들링 함수에서 files로부터 첫번째 파일을 선택해야하는데, file이라고 적어서 오류가 발생했다.

제출 시 오류

아직 API 구현하지 않았으니 오류 발생하는게 맞음.
그래도 개발자 도구로 네트워크 살펴보면 데이터 자체는 제대로 넘기는 것을 확인 가능하다.

이름이 파일 이름으로 들어간다?

addCustomer() 함수 구현할 때 fileName이 넘어가게 만들어 놓았음.
userName으로 수정하니 제대로 넘어감.

제출하면?

POST 방식으로 해당 API에 전달되는 것을 확인할 수 있다.


(다음 게시물에서 계속...)

profile
🚙 HMG SOFTEER 3rd | 💻 BE

0개의 댓글