[ React ] select 태그, warning: Use the 'defaultValue' or 'value' props on <select> instead of setting 'selected' on <option>

양찌·2022년 1월 15일
0

React

목록 보기
4/4
post-thumbnail

들어가기 전...
회원가입 폼을 만드는데 많은 오류가 났다..
1. 서버 end포인트 오류 https에 요청보내야 할 것을 https에 요청
2. select 폼 안에 다수의 option태그로 이루어진 birth속성이 바뀌지 않음(birth속성을 객체로 만들어 따로 상태로 관리 해줌으로써 해결)
3. select 옵션의 핸들링


✍ 문제

이 포스팅에 다룰 문제는 위에 보기에서 3번이다.
바로 warning: Use the 'defaultValue' or 'value' props on <select> instead of setting 'selected' on <option> 이 에러 핸들링에 관하여 어떻게 해결 하였는지 작성해본다.




✍ 해결책

내가 완성한 최종 UI는 다음과 같다.

즉, 생년월일 선택란에서는 월을 선택하기 전에 "월"이라는 글자가 보인다.
그리고 성별 선택란에서는 성별을 선택하기 전에 "성별"이라는 글가자 보인다.

맨 처음에 <option selected> option태그에 selected 속성을 작성했는데 앞에 언급했던 에러를 만났다.
에러를 검색해봤는데 react 공식문서에 따르면 다음과 같이 나와있었다.

React에서는 selected 어트리뷰트를 사용하는 대신 최상단 select태그에 value 어트리뷰트를 사용합니다.
-react 공식문서-

react 공식문서에서는 selected 속성 대신에 default value 값 자체를 처음부터 기본으로 될 값을 저장하였다.
그래서 나도 같은 방식으로 문제를 해결하였다.

1. 기본값을 원하는 값으로 처음에 설정

// 기본값을 '성별'로 정의
const [ userState, setUserState ] = useState({
  login_id: '',
  password: '',
  repassword: '',
  nickname: '',
  name: '',
  birth: '',
  gender: '성별'
});


// ... 코드 생략 ...
<label htmlFor="gender">성별</label>
<span className={`${styles.wd_460} ${styles.genderBox}`}>
<select 
  name="gender"
  vlaue={gender || ''}
  onChange={onChangUpdateState}
>
<option value="성별" >성별</option>
<option value="M">남자</option>
<option value="F">여자</option>
<option value="U">선택안함</option>
</select>
</span>



2. option태그를 따로 분리

월 같은 경우 1월~12월까지 있다. 그래서 배열안에 1월부터 12월까지 값을 너어놓고 .map()메소드를 이용하는 방식으로 코드를 작성하였다.
이 방법 사용시 굳이 처음에 "월"이라는 값을 default value로 저장을 하지 않아도 되었다.
<option value="">월</option>을 먼저 정의 후에 .map()메소드를 사용하였더니 가장 처음 기본값으로 자동으로? 랜더링이 되었다.

// birth 기본값 정의 하지 않음.
const [ userState, setUserState ] = useState({
  login_id: '',
  password: '',
  repassword: '',
  nickname: '',
  name: '',
  birth: '',
  gender: '성별'
});

// birth.mm 과 같은 object형식으로 저장이 되어야 함으로 상태를 따로 관리
const [ birthState, setBirthState ] = useState({
  yy: '',
  mm: '',
  dd: ''
});

// 월들을 배열로 정의
const months = ['01', '02', '03', '04', '05', '06', '07', '08', '09', '10', '11', '12'];

// ... 코드생략...

<select
  name="mm"
  value={mm || ''}
  onChange={onChangUpdateState}
  onBlur={onBlurBirth}
>
  <option value=""></option>
   {months.map((m, idx) => // 월의 값을 맵핑해주기 
     <option key={idx} value={m}>{m}</option>
   )}
</select>

회원가입 페이지 생각보다 손 볼때도 많았고, 생각할 부분도 많았던 페이지 였던 것 같다. 휴 그래도 잘 마무리 하여 뿌듯하다. ㅎㅎ 😄🙌

profile
신입 개발자 입니다! 혹시 제 글에서 수정이 필요하거나, 개선될 부분이 있으면 자유롭게 댓글 달아주세요😊

0개의 댓글