[코드잇] 제어컴포넌츠 / 비제어 컴포넌츠 - 파일 < input > 하기

iberis2·2023년 4월 10일
0

React 리액트

목록 보기
16/20

제어컴포넌츠

<input>value 를 리액트에서 지정함

리액트에서 사용하는 값과 실제 <input>의 값이 항상 일치한다.

  • 동작을 예측하기 쉽고,
  • <input> 값을 여러 곳에서 쉽게 바꿀 수 있다.
    • 위 Sandbox 에서 App 와 MyComponent 에서 각각 title의 상태를 관리할 수 있다.

비제어컴포넌츠보다는 주로 제어컴포넌츠를 사용하길 권장된다.


비제어컴포넌츠(Uncontrolled Component)

<input>value 값을 리액트에서 지정하지 않음

  • state값과 실제 입력 값이 다를 수 있다.

<input>에 입력하는 값을 직접 제어하지 않고, 값에 대해 참조가 필요한 경우 폼 태그를 참조해서 input의 값을 사용할 수 있다

① 이벤트 객체의 target 활용하는 방법

export default function App() {
  
  const onSubmit = (e) => {
    e.preventDefault();
    
    const form = e.target; 
    const location = form["location"].value; // "location" input값이 필요한 경우
    const checkIn = form["checkIn"].value; // "checkIn" input값이 필요한 경우
    const checkOut = form["checkOut"].value; // "checkOut" input값이 필요한 경우
  };
  
  return (
    <div className="App">
      <form onSubmit={onSubmit}>
        <h1>검색 시작하기</h1>
        <label htmlFor="location">위치</label>
        <input id="location" name="location" placeholder="어디로 여행가세요?" />

        <label htmlFor="checkIn">체크인</label>
        <input id="checkIn" type="date" name="checkIn" />

        <label htmlFor="checkOut">체크아웃</label>
        <input id="checkOut" type="date" name="checkOut" />

        <button type="submit">검색</button>
      </form>
    </div>
  );
}

② 폼 태그로 곧바로 FormValue를 만드는 방법

const handleSubmit = (e) => {
  e.preventDefault();
  const form = e.target;
  const formValue = new FormValue(form);
  // ...
}

파일 Input

<input type="file" /> 은 반드시 비제어 인풋(uncontrolled input)으로 만들어야 한다.

제어 인풋으로 만들면 (=인풋에 value 속성을 지정하면)
🚨Warning : A component is changing an uncontrolled input to be controlled. 에러 메세지가 나오게 된다.

만약 파일 input 의 value 를 파일 이름으로 지정하면
🚨 This input element accepts a filename, which may only be programmatically set to the empty string 에러 메세지가 나온다.

  • 보안문제로 인해 HTML에서 파일input은 반드시 사용자만 값을 바꿀 수 있고, 자바스크립트는 값을 바꿀 수 없다.
    따라서 굳이 value 속성을 넣는다면, 자바스크립트로는 빈 문자열로만 설정할 수 있다. <input type="file" value="">
function FileInput() {
  const onChange = (e) => {
    console.log(e.target.value);
  };
  
  return (
    <div>
      <input type="file" onChange={onChange} />
    </div>
  );
}
  • [코드] file 인풋의 value를 콘솔에 출력

  • [사진] 파일의 경로를 숨겨주는 HTML

HTML에서 파일의 경로를 숨겨주기 때문에 value를 콘솔에 출력해보면 fakepath 가 나온다.

그럼 파일 인풋 <input type="file" /> 은 어떻게 다뤄야할까?

function FileInput() {
  
  const onChange = (e) => {
    console.log(e.target.files[0]);
  };
  
  return (
    <div>
      <input type="file" onChange={onChange} />
    </div>
  );
}
  • [코드] console.log( event.target.files[0] )

  • [사진] 파일 input 은 유사배열 객체

event.target.files 로 구체적인 속성을 찾아볼 수 있는데, 유사배열객체로 이루어져 있다.

파일을 넣고 0번째 인덱스를 출력해보면 프로퍼티로 lastModified, lastModifiedDate, name, size, type, webkitRelativePath 등의 속성이 있다.

해당 속성을 가지고 필요에 따라 아래 코드처럼 원하는 상태값들을 활용해볼 수 있을 것이다.


profile
React, Next.js, TypeScript 로 개발 중인 프론트엔드 개발자

0개의 댓글