동일한 UI의 input태그들을 map을 돌리고 있을 경우, 이 input 태그들 중 특정 input 태그의 value 값만 따로 뽑아내려면 어떻게 해야할까 ?
(참고로 input 태그는 컴포넌트!
input 태그 내에 들어가는 텍스트들은 상수데이터화! -> map 돌릴 때 data 로 input 컴포넌트에 넘겨주고 있다)
{INFOINPUT_LABEL_VALUE.map(data => {
return (
<InfoInput
key={data.id}
label={data.value}
name={data.name}
infoInputValue={infoInputValue}
setInfoInputValue={setInfoInputValue}
/>
);
})}
const INFOINPUT_LABEL_VALUE = [
{ id: 1, name: 'name', value: '수령인 성함' },
{ id: 2, name: 'phoneNumber', value: '수령인 전화번호' },
{ id: 3, name: 'addressCode', value: '우편번호' },
{ id: 4, name: 'address', value: '주소' },
{ id: 5, name: 'addressDetail', value: '상세주소' },
];
계산된 속성명을 사용할 차례였던 것이다.
옛날에 로그인/회원가입에만 사용해보았었고, 그 마저도 멘토님의 코드를 봐가며 했던 거라 온전히 내 지식이 되지 않았다.
이번에도 누군가의 도움을 받으며 구현한거라, 여전히 내 지식은 아니지만
내 지식으로 만들려고 이렇게 벨로그 정리중 ! 📝📝📝 진짜 울고싶당 🥲
input 태그 속성으로 " name " 이라는 속성을 줄 수 있다.
말 그대로 태그에 이름을 부여해주는 것이다.
그래서 input 정보를 담고 있는 상수데이터에 name 을 추가해주었다.
map 으로 돌아가는 input 태그에 차례대로 name 값이 부여될 것이다.
const INFOINPUT_LABEL_VALUE = [
{ id: 1, name: 'name', value: '수령인 성함' },
{ id: 2, name: 'phoneNumber', value: '수령인 전화번호' },
{ id: 3, name: 'addressCode', value: '우편번호' },
{ id: 4, name: 'address', value: '주소' },
{ id: 5, name: 'addressDetail', value: '상세주소' },
];
❗️ 나는 여기서 address 라는 name 을 가진 input 의 value 값이 필요했다.
그래서 name 을 가진 input 태그들의 정보를 받기 위해, 상단에 객체를 하나 생성해주어야 했다. 그리고 그 객체 내에 들어갈 정보를 관리해주는 state 가 필요했다.
const initialInfoInput = {
name: '',
phoneNumber: '',
addressCode: '',
address: '',
addressDetail: '',
};
const [infoInputValue, setInfoInputValue] = useState(initialInfoInput);
나는 input 의 value 값이 필요했기에,
input 에서 발생되는 value 정보들을 관리해주어야 했다.
( 쓰면서도 어렵다 으아아아아앙 )
infoInputValue 의 초기값이 현재 저 객체(initialInfoInput) 이니,
setInfoInputValue 에 원하는 정보들이 잘 담길 수 있도록 기능의 구조를 짜주어야 했다.
function InfoInput({ label, name, infoInputValue, setInfoInputValue }) {
const [move, setMove] = useState(false);
const onFocusInput = () => {
setMove(true);
};
const onBlurInput = e => {
const { name } = e.target;
infoInputValue[name] !== '' ? setMove(true) : setMove(false);
};
const saveInputValue = e => {
const { name, value } = e.target;
setInfoInputValue(prev => ({ ...prev, [name]: value }));
};
return (
<div className={`orderTextInput${move ? ' move' : ''}`}>
<input
type="text"
name={name}
onFocus={onFocusInput}
onBlur={onBlurInput}
onChange={saveInputValue}
/>
<label>{label}</label>
</div>
);
}
export default InfoInput;
☝🏻 앞서 말했듯이 Input 자체가 컴포넌트. (InfoInput)
현재 상수데이터의 데이터들과 state 값을 props 로 받고 있음.
function InfoInput({ label, name, infoInputValue, setInfoInputValue }) {
return (
<div className={`orderTextInput${move ? ' move' : ''}`}>
<input
type="text"
name={name}
onFocus={onFocusInput}
onBlur={onBlurInput}
onChange={saveInputValue}
/>
<label>{label}</label>
</div>
);
}
infoInput 컴포넌트에서 데이터를 뽑아내야 해서, 여기서 기능 구조를 짜주어야 한다.
상위 컴포넌트에서 미리 설정해둔 state 들을 props 로 내려준다.
Input 의 발생하는 value 값들을 실시간으로 받아오려면, onChange 이벤트가 사용돼야 한다.
그래서 onChange 안에 들어갈 함수(기능)이 필요했다.
const saveInputValue = e => {
const { name, value } = e.target;
setInfoInputValue(prev => ({ ...prev, [name]: value }));
};
onChange 이벤트를 통해, e.target 을 사용할 수 있다.
infoInputValue 에 초기값으로 설정해준 객체 모양을 맞춰줘야 하기 때문에,
props 로 넘겨준 name 과 value 를 객체구조할당 해준다.
( e.target.name, e.target.value )
setInfoInputValue 를 통해, infoInputValue 에 정보를 잘 담아줄 준비를 한다.
이전의 정보들 (prev) 을 먼저 풀어 담아주고, 그 뒤에 e.target.name 을 key 값으로, e.target.value 를 name의 값으로 담아주는 형식을 만든다.
( prev 라는 것은 그럼... initialInfoInput 의 정보를 말하는 걸까? )
저 함수, saveInputValue를 input태그 onChange 이벤트에 넣어준다.
그러면! input 창에 입력되는 값이 실시간으로 infoInputValue에 설정해준 구조로 찍힌다!
👇🏻 console.log(infoInputValue)
나는 address 의 value 값이 최종적으로 필요했기에 !!!
infoInputValue.address 로 접근하여 value를 뽑아낼 수 있었다 🥹