이롭게 현명하게

[React] 리액트 사용자 입력 / input 상태 관리 본문

웹 개발/React

[React] 리액트 사용자 입력 / input 상태 관리

dev_y.h 2023. 12. 26. 18:50
728x90
반응형

※ 본 포스팅은 윈도우11 환경에서 패스트 캠퍼스 강의를 수강하며 정리한 내용입니다.


 

목차

 

input 상태 관리하기

여러 개의 input 상태 관리하기

 



[input 상태관리하기]

코드를 실행하면 다음과 같은 화면이 나온다.

useState와 onChange 이벤트를 사용해 값을 입력하면 하단에 나타나도록 했다.

// InputSample.js //

import React from "react";

function InputSample(){
    return(
        <div>
            <input/>
            <button>초기화</button>
            <div>
                <b>값</b>
                어쩌고 저쩌고
            </div>
        </div>
    );
}

export default InputSample;
// App.js //

import React from "react";
import InputSample from "./InputSample.js";

function App() {

  return (
    <InputSample/>
  );
}

export default App;

 


리액트에서는 input 값을 useState 함수를 사용하여 변경되는 값을 관리한다.

onChange 이벤트는 HTML 요소의 값이 변경될 때 발생한다.

input의 onChange를 사용하면 이벤트 객체 e를 파라미터로 받아올 수 있다.

이 객체의 e.target은 이벤트가 발생한 DOM인 input DOM을 가리키게 된다.

e.target.value를 조회하면 현재의 input의 value 값을 알 수 있다.

 

<예시 코드>

// InputSample.js //

import React,{useState}  from "react";

function InputSample(){
    const [text,setText] = useState('');
    const onChange = (e)=>{
        setText(e.target.value);
    }

    const onReset = ()=>{
        setText('');
    }
    return(
        <div>
            <input onChange={onChange} value={text}/>
            <button onClick={onReset}>초기화</button>
            <div>
                <b>값: </b>
                {text}
            </div>
        </div>
    );
}

export default InputSample;

 

onChange 이벤트 : 수정 이벤트가 발생했을 때 그 이벤트에 대한 내용이 이벤트 객체 파라미터로 받아와져서 사용할 수 있게 된다.

e.target : 현재 input으로 이벤트가 발생한 DOM에 대한 정보를 가지고 있다.

e.target.value : 현재 input에 입력한 값이 무엇인지 알 수 있다. DOM의 value값

setText(e.target.value) : input에 입력된 값을 {text}에서 보여준다.

onReset() : 초기화 기능함수

setText('') : input 값을 비운다.

value={text} : 초기화 버튼을 눌렸을 때 input에 있는 값이 비워진다.

{text} : 입력된 값이 출력된다.

 


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

input 태그가 하나일 때는 target이 하나여서 e.target.value를 통해 input에 입력한 값이 무엇인지 알 수 있었다.

input의 개수가 여러 개일 때는 단순히 useState를 여러번사용하고 onChange도 여러 개를 만들어서 구현하면 될 거라 생각했다.

하지만 이 방법은 좋은 방법이 아니다.

더 좋은 방법은 input에 name을 설정하고 이벤트가 발생했을 때 이 값을 참조하는 것이다.

그리고 useState에서는 문자열이 아닌 객체 형태의 상태를 관리해 주어야 한다.

<객체 상태 업데이트>

  1. 기본 상태를 한번 복사한다.
  2. 거기에 특정 값을 덮어씌워 그것을 새로운 상태로 설정한다.

이런 것을 불변성을 지킨다고 한다.

불변성을 지켜줘야 리액트 컴포넌트에서 상태가 업데이트되었음을 감지할 수 있다.

이에 따라 필요한 렌더링이 발생한다.

 

import React,{useState}  from "react";

function InputSample(){
   
    const onChange = (e)=>{
        
    }

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

export default InputSample;

placeholder : input이 비어져있을 때 input에 대한 설명을 보여준다.

 


<예시 코드>

import React,{useState}  from "react";
function InputSample(){
    const [inputs,setInputs] = useState({
        name:'',
        nickname:''
    });
    const {name,nickname} = inputs; // 비구조화 할당으로 추출
    const onChange = (e)=>{
    const {name,value} = e.target;//e.target에서 name과 value를 추출
    //1번 방법
    /*
    const nextInputs={
            ...inputs,//기존의 객체를 복사한다.
            [name] : value
     }
    setInputs(nextInputs)
    */
     //2번 방법
    setInputs({
        ...inputs
        [name]:value});
    }
    const onReset = ()=>{
        setInputs({
            name:'',
            nickname:''
        })
    }
    return(
        <div>
            <input name="name" placeholder="이름" onChange={onChange} value={name}/>
            {/*여기서 이벤트가 발생했을 때 e.target.value값을 조회했다. 
            만약 e.target.name을 조회하면 name의 값이 나타나게 된다.*/}
            <input name="nickname" placeholder="닉네임" onChange={onChange} value={nickname}/>
            <button onClick={onReset}>초기화</button>
            <div>
                <b>값: </b> {name}({nickname})
            </div>
        </div>
    );
}
export default InputSample;
// App.js //

import React from "react";
import InputSample from "./InputSample.js";

function App() {

  return (
    <InputSample/>
  );
}

export default App;

 


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

기본값으로 name,nickname이 있고 공백으로 설정해 주었다.

 

const {name,nickname} = inputs;

name과 nickname을 쉽게 사용할 수 있도록 비구조화할당을 통해 추출해 주었다.

 

const {name,value} = e.target;

e.target에서 name과 value를 추출

비구조화 할당을 통해 e.target에서 name과 value를 추출한다.

 

 

리액트 상태에서 객체를 수정해야 할 때는 inputs[name] = value; 이런 식으로 수정하면 안 된다.

새로운 객체를 만들어서 새로운 객체에 변화를 주고 이를 상태로 사용해야 한다.

setInputs(value)를 해도 되지만 리액트에서 객체를 업데이트하는 방법이 다르다.

기존의 객체를 복사해야한다.

setInputs({
	...inputs
    [name] : value
});

...inputs : 기존의 객체를 복사한다.

  • ... : spread 문법
  • ...inputs는 기존에 있는 inputs 내용이 복사된다.

[name] : value : name 키를 가진 값을  value로 설정

  • name : value 는 특정 값을 덮어 씌운다. 문자열 name자체가 들어가게 된다.
  • 그런경우 대괄호로 감싸줘야한다.
  • [name] : value 는 실제 name 값이 무엇을 가리키고 있느냐에 따라 다른 키 값이 변경된다.

 

만약 inputs[name] = value 형식으로 기존 상태를 직접 수정하게 되면 값을 바꿔도 렌더링 되지 않는다.

... 문법 : spread 문법으로 객체의 내용을 모두 "펼쳐서" 기존 객체를 복사해준다.

 


리액트에서는 불변성을 지켜줘야 한 컴포넌트 업데이트 성능을 최적화를 제대로 할 수 있다.

리액트에서 객체를 업데이트하게 될 때에는 기존 객체를 수정하면 안 되고 새로운 객체를 만들어서 새 객체에 변화를 줘야 한다.

 


잘못된 정보는 댓글에 남겨주시면 감사하겠습니다!😊

댓글과 좋아요는 큰 힘이 됩니다!

 

 

728x90
반응형
Comments