본문 바로가기
frontend/React

[React]TS로 개발할 때 input 값 여러 개 받기

by BK0625 2023. 3. 23.
반응형

리액트로 사이드 프로젝트를 개발하던 도중 input 값을 여러 개 받아야 되는 경우가 생겼다. 해당 항목마다 state를 만들고 onChage 함수도 따로 만들어 각각 달아주는 방법도 있지만 중복 코드도 많고 쓸 데 없는 작업이 많아지기 때문에 별로 좋은 방법이라고 생각되지 않았다. 따라서 state 하나에 onChange 함수 하나를 만들어 여러개 input 값을 받는 방법을 포스팅한다.

 

 

 return (
        <div className="card">
            <Card title="Sign Up">
                <div className="card flex justify-content-center">
                    <div className='login-input'>
                        <h1 className="login">ID  &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </h1>
                        <InputText className='userId' placeholder='userId' onChange={(e)=>onChangeUserInfo(e)}/>
                    </div>
                    <div className='login-input'>
                        <h1 className="login ">PW&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </h1>
                        <Password className='password' placeholder='password' feedback={true} onChange={(e)=>onChangeUserInfo(e)}/>
                    </div>
                    <div className='login-input'>
                        <h1 className="login ">NAME&nbsp;&nbsp;&nbsp;</h1>
                        <InputText className='name' placeholder='name' onChange={(e)=>onChangeUserInfo(e)} />
                    </div>
                    <div className='login-input'>
                        <h1 className="login ">School&nbsp;&nbsp; </h1>
                        <InputText className='school' placeholder='school' onChange={(e)=>onChangeUserInfo(e)} />
                    </div>
                    <div className='login-input'>
                        <h3 className="login ">Mother email&nbsp; </h3>
                        <InputText className='motherEmail' placeholder='motherEmail' onChange={(e)=>onChangeUserInfo(e)} />
                    </div>
                    <div className='login-input'>
                        <Button onClick = {()=>console.log(user)} label="Sign up" />
                    </div>
                </div>
            </Card>
        </div>
    )

 

 

 

현재 회원가입 기능 구현 중에 있는데 이렇게 아이디, 비밀번호, 이름, 학교, 부모님 이메일을 입력 받아야 한다. 즉 만약 onChange 함수를 따로 만들어주면 총 5개를 만들어야 되고 입력 받아야할 항목이 늘어날수록 코드는 기하급수적으로 늘어날 것이다. 따라서 하나의 함수로 하나의 state에 모든 값을 담아야 한다.

 

 

 

interface userJoin{
    userId:string,
    password:string,
    name:string,
    school:string,
    motherEmail:string
}

 

 

 

먼저 interface를 선언해 useState에 들어갈 타입을 명시한다.

 

 

    const onChangeUserInfo = (e:React.ChangeEvent<HTMLInputElement>) => {
       
       //console.log(e.target)
        const { placeholder, value } = e.target;
       
        setUser({...user,[placeholder]:value})

    }

 

 

그 다음 onChangeUserInfo 함수를 만들어주는데 이벤트의 타입은 input 입력 이벤트이기 때문에 React.ChangeEvent<HTMLInputElement로 명시해준다. 사용하는 리액트 컴포넌트 라이브러리 상 className 값을 읽어오지 못 하기 때문에 (정확히는 라이브러리에서 이미 InputText의 className을 정의를 해버렸다.) placeholder를 사용해서 구분해준다. user의 state를 선언할 때 꼭 값을 초기화를 해줄 것! 안해주면 타입 에러가 난다. 그래서

 

 

const { placeholder, value } = e.target;

 

 

 

이 부분으로 값을 받은 뒤에 spread 문법으로 객체의 내용을 모두 펼쳐서 기존 객체에 복사한 뒤 입력 값을 해당 부분에 붙여주면 된다.

 

 

 setUser({...user,[placeholder]:value})

 

 

 

절대 input[name] = value 식으로 값을 바꿔서는 안된다. 그렇게 되면 값이 바뀌더라고 리렌더링이 일어나지 않기 때문!

 

 

 

 

 

 

 

 

 

값이 잘 들어온 것을 확인할 수 있다.

 

주로 백엔드 파트를 주로 맡았어서 리액트에서는 아직 부족한 부분이 많은 거 같다. 조금씩 조금씩 채워나가야지

반응형