[에러핸들링] input file value 에러

hyo·2023년 2월 14일
0
post-thumbnail

input file value 값 넣어주기


위와 같이 파일업로드를 하였을때 input태그에 파일이름이 출력되게끔 구현 하고 싶었다.
하지만 에러가 발생하였고 해결하기 위해 여러가지 방법을 써본 결과 방법을 찾았다.

우선 나는 react-hook-form 라이브러리를 사용하여 구현중이다.
input file 태그는 <input type='file' {...register('photoURL')}> 으로 써두고 커스텀 하기 위해 label 태그도 썻지만 아래 해결 과정에는 간단한 예시로 설명하겠다.

<div>
  {watch('photoURL') ? 
  <input type='text' value={watch('photoURL')[0]['name'] /> 
  : <input type='text' value=' /> }
  <input type='file' {...register('photoURL')}/>
</div>

처음엔 위처럼 코드를 쓰고 실행시켜보았지만 에러가 나왔다.
property를 읽을 수 없고 정의 되지 않는다고 나왔다.
watch('photoURL')이 true일때만 watch('photoURL')[0]['name']라고 써둔 코드가 읽힐 줄 알았지만 watch('photoURL')이 false일때에도 일단 읽히고 있는 것이다.

일단 watch('photoURL')에 값이 콘솔에는 어떻게 출력되는지 알아보자.

위 아래 순서대로 watch('photoURL')에 값이 없을때와 있을때이다.

watch('photoURL')의 값이 있을때 콘솔에 찍힌 FileList를 분석해보자.

파일 name, size, type 등 정보의 키값쌍으로 이루어진 객체이다.

위와 같은 객체형태로 이루어져 있어서
watch('photoURL')[0]['name']으로 값을 불러오는 중이다.
여기서 의문이 몇가지가 있는데 0이라는 키를 가진 FileList 이지만
braketNotation으로 [0]이라고 써도 출력이 되었다. -> ['0'] 이미 주어진 키라면 이렇게 써야하는걸로 아는데..왜그런진 모르겠다..

에러 1.

Warning: You provided a valueprop to a form field without anonChangehandler. This will render a read-only field. If the field should be mutable usedefaultValue. Otherwise, set either onChangeorreadOnly.
-> 경고: onChange 핸들러 없이 양식 필드에 value 소품을 제공했습니다. 이것은 읽기 전용 필드를 렌더링합니다. 필드가 변경 가능해야 하는 경우 defaultValue를 사용하십시오. 그렇지 않으면 onChange 또는 readOnly를 설정합니다.

위의 에러는 input 속성의 value를 defaultValue로 줘서 없앴다.

에러 2.

Warning: A component is changing an uncontrolled input of type undefined to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component.
-> 경고: 구성 요소가 정의되지 않은 유형의 제어되지 않은 입력을 제어하도록 변경하고 있습니다. 입력 요소는 제어되지 않은 상태에서 제어된 상태로(또는 그 반대로) 전환되지 않아야 합니다. 구성 요소의 수명 동안 제어되는 입력 요소를 사용할지 또는 제어되지 않는 입력 요소를 사용할지 결정하십시오.

위의 에러와 property를 읽을 수 없다는 에러는
useState()를 사용하여 파일업로드를 하지 않았을때에는 '' 빈 문자열을 value속성값으로 주고 파일업로드를 하였을 시에는 파일 이름을 로컬 상태인 useState로 저장하여 input value에 불러오는 식으로 코드를 썻더니 원하는 결과가 나왔다.


const MyProfile = () => {
  const [img, setImg] = useState('');

  useEffect(() => {
    if(watch('photoURL')) {
       setImg(watch('photoURL')[0]['name'])
     }
  }, [watch('photoURL')])

  return (
    <div>
    <input
       type="text"
       defaultValue={watch('photoURL') ? img : ''}
    />
    <input type='file' {...register('photoURL')}/>
    </div>
  )
}
profile
개발 재밌다

0개의 댓글