React | 계산된 속성명 사용하여 필요한 데이터 뽑아내기

앙두·2023년 1월 25일
1

React

목록 보기
13/20

⚡️ 문제 발생

동일한 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를 뽑아낼 수 있었다 🥹

profile
쓸모있는 기술자

0개의 댓글