[React]여러개의 input 상태 관리하기

devHagaa·2022년 8월 24일
5

React

목록 보기
8/9
post-thumbnail
post-custom-banner

input 여러 개 일때 useState를 여러개 사용하는건 좋은 방법이 아님.
좋은 방법은, input에 name이라는 값을 설정하고, 이벤트가 발생했을 때 이값을 참조하는거다.

여러개의 문자열 형태를 가지고 있는 객체 형태를 관리 해 줘야한다.

function InputSample(){
    const [inputs, setInputs] = useState({
        name:'',
        nickname:'', 
    });
    const {name, nickname} = inputs;

    const onChange = (e)=>{
        console.log(e.target.name);
        console.log(e.target.value);
    }

    const onReset = ()=>{
        
    }
    return (
        <div>
            <input name="name" placeholder="이름" onChange={onChange}/>
            <input name="nickname" placeholder="닉네임" onChange={onChange}/>
            <button onClick={onReset}>초기화</button>
            <div>
                <b>값: </b>
                이름 (닉네임)
            </div>
        </div>
    );
}

export default InputSample;

이 값들을 참조해서 객체를 업데이트 해 주면 되는건데,

1.리액트에서 객체를 업데이트 할 때

기존의 객체를 복사 해야한다.
...inputs 이건 spread문법인데 이 문법은 객체 혹은 배열을 펼칠 수 있다.
https://learnjs.vlpt.us/useful/07-spread-and-rest.html?q=


function InputSample(){
    const [inputs, setInputs] = useState({
        name:'',
        nickname:'', 
    });
    const {name, nickname} = inputs;

    const onChange = (e)=>{
        const {name, value} = e.target;

        const nextInputs = {
            //spread 문법. 현재 상태의 내용이 이 자리로 온다. 
            ...inputs,
            [name] : value,
        };
        //객체를 새로운 상태로 쓰겠다. 
        setInputs(nextInputs);
    };

    const onReset = ()=>{
        
    };
    
    return (
        <div>
            <input name="name" placeholder="이름" onChange={onChange}/>
            <input name="nickname" placeholder="닉네임" onChange={onChange}/>
            <button onClick={onReset}>초기화</button>
            <div>
                <b>값: </b>
                이름 (닉네임)
            </div>
        </div>
    );
}

export default InputSample;

nextInputs 에 ...inputs을 사용해서 input한거 그대로 사용 하면서 name만 value로 덮어준다.

const nextInputs = {
            //spread 문법. 현재 상태의 내용이 이 자리로 온다. 
            ...inputs,
            name:value,
        };

이렇게 하면 문자열 name자체가 들어가지게 되는데

[name]:value,

해주면 name값에 따라 다른 key값이 변경됨.

input이 세개 이상이어도 문제없다.

import React, { useState } from 'react'

const InputComponent = () => {
    const [input, setInput] = useState({
        input1: '',
        input2: '',
        input3: ''
    })

    const { input1, input2, input3 } = input; // destructuring

    const onChangeInput = (e) => {
        const {name, value} = e.target // destructuring
        setInput({
            ...input,
            [name]:value
        })
    }



    return (
        <div>
            <input type="text" name="input1" value={input1} onChange={onChangeInput}/>
            <input type="text" name="input2" value={input2} onChange={onChangeInput}/>
            <input type="text" name="input3" value={input3} onChange={onChangeInput}/>
        </div>
    )
}

export default LoginPage

2. map함수 안에서 다이나믹하게 input 상태관리하기

만약 React JSX문법에서 .map내부에 Dynamically change input's name을 하고 싶다면 어떻게 할까?

예시를 보면

{this.props.items.map((item, idx) => (
<input type="text" name="name{idx}" ... />
))}

map함수를 사용해서 name값에 고정된 string과 idx를 합쳐서 부여하고 싶다고 가정하자.

name="name0"
name="name1"
name="name2"
...

이런 식으로 표현하려면 ${}에 변수를 사용해주거나

<input type="text" name = {`name${idx}`} ... />

"string" + 변수로 표현해 주면 된다.

<input type="text" name = {"name" + idx} ... />

아래는 위에 적힌 두가지를 모두 적용한 예제 코드이다.
import React, { useState } from 'react'

const InputComponent = () => {
  const [input, setInput] = useState({
      input0: "",
      input1: "",
      input2: "",
      input3: "",
      input4: "",
  });
  
  const handleTextValueChange = (e) => {
      const { name, value } = e.target;
      setInput((input) => {
        return { ...input, [name]: value };
      });
  };
  
  return (
      {uniqueArr.map((index) => (
          <input
              type="text"
              id={`input${index}`}
              name={`input${index}`}
              placeholder="변수입력"
              onChange={handleTextValueChange}
              value={`input${index}`.value}
          />
      ))}
  )
}

export default LoginPage

정리

객체 상태를 업데이트 할 때는 꼭 기존의 상태를 한번 복사하고 나서 특정값을 덮어 씌우고 새로운 값을 설정 해주어야함. : 이걸 불변성을 지켜준다고 함.
이렇게 해야 업데이트 된 것을 감지하고 랜더링이 됨.

객체 상태를 업데이트 할 때는 spread문법으로 객체를 복사하고, 특정값을 덮어씌워서 상태를 업데이트 해 주어야한다.

이건 배열 상태를 관리 할 때에도 마찬가지이고 불변성을 지켜줘야지만 최적화도 되는 것이다.

profile
디자이너인가 퍼블리셔인가 프론트엔드개발자인가 정체성의 혼란을 겪는 개린이
post-custom-banner

0개의 댓글