[React.js] React에서 사용자 입력 처리하기

2022. 5. 14. 09:56·공부/React.js
반응형

 

React 게시글은 대부분 인프런의 '한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지' 강의를 기반으로 내용을 정리했습니다.

 

React에서 사용자 입력 처리하기

새로운 프로젝트를 만들자.

npx create-reace-app simplediary

 

불필요한 파일은 삭제한다.

 

삭제한 파일과 관련된 코드들을 지운다.

App.js

import './App.css';

function App() {
  return (
  <div className="App">
    <h2>일기장</h2>
  </div>
  );
}

export default App;

index.js

import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

Terminal

npm start

프로젝트가 에러 없이 잘 구동되는지 확인한다.

반응형

 

오늘 만들 다이어리

 

다이어리의 에디터 부분을 만들기 위해 새로운 파일을 생성한다.

const DiaryEditor = () => {
    return <div className='DiaryEditor'></div>
}

export default DiaryEditor;

 

모듈 생성 후 화면에 랜더 할 수 있도록 App.js에 코드를 추가한다.

import './App.css';
import DiaryEditor from './DiaryEditor'; // 추가

function App() {
  return (
  <div className="App">
    <h2>일기장</h2>
    <DiaryEditor/> <!--추가-->
  </div>
  );
}

export default App;

DiaryEditor 확인

이제 다이어리에 작성자를 입력할 수 있도록 input 태그를 추가한다.

DiaryEditor.js

const DiaryEditor = () => {
    return (
    <div className='DiaryEditor'>
        <h2>오늘의 일기</h2>
        <div>
            <input />
        </div>
    </div>
    );
};

export default DiaryEditor;
반응형

 

input 태그를 핸들링하기 위한 코드를 작성하자.
input 태그는 작성자를 나타내며 상태를 가질 수 있다.
그래서 저번에 배웠던 State를 사용해 input을 핸들링해보자.

import {useState} from "react"; // 추가

const DiaryEditor = () => {

    const [author,setAuthor] = useState(""); // 추가

    return (
    <div className='DiaryEditor'>
        <h2>오늘의 일기</h2>
        <div>
            <input value={author} /> // 추가
        </div>
    </div>
    );
};

export default DiaryEditor;

useState를 사용하기 위해 react를 import 시켜준다.
그리고 모듈 내에 State를 사용하기 위해 변수와 함수 그리고 초깃값을 지정한다. 현재 초기값은 빈 문자열이다. 
지금 이 코드에서 화면 input에 값을 아무리 입력해도 빈 문자열을 그대로 유지하고 있는데 그 이유는 input 태그의 value가 author로 설정되어 있는데 author의 값은 상태변화 함수인 setAuthor를 사용하지 않았기 때문이다. input 태그에서 author값을 변경하고 싶다면 아래 코드처럼 작성하면 된다.

import {useState} from "react";

const DiaryEditor = () => {

    const [author,setAuthor] = useState("");

    return (
    <div className='DiaryEditor'>
        <h2>오늘의 일기</h2>
        <div>
            <input value={author} 
            onChange={(e)=>{
                console.log(e);
                console.log(e.target.value);
                setAuthor(e.target.value);
            }}
            />
        </div>
    </div>
    );
};

export default DiaryEditor;

 

onChange는 Event 중 하나이다. 이벤트는 사용자가 어떤 행동을 했을 때 호출된다. onChange는 input 값에 상태가 변경됐을때(입력 됐을때) 발생한다. onChange 이벤트에 등록되는 콜백 함수에서는 e를 매개변수로 받는다. 콜백 함수 내에서 콘솔로 e를 찍어봤을 때 아래처럼 객체가 나온다. 이 객체 안의 프로퍼티 중 target.value 값을 이용해 현재 값을 받아올 수 있다.

이제 일기 내용을 작성할 textarea 부분을 구현해보자.

import {useState} from "react";

const DiaryEditor = () => {

    const [author,setAuthor] = useState("");
    const [content,setContent] = useState("");
    
    return (
    <div className='DiaryEditor'>
        <h2>오늘의 일기</h2>
        <div>
            <input value={author} 
            onChange={(e)=>{
                setAuthor(e.target.value);
            }}
            />
        </div>
        <div>
            <textarea valeu={content} 
            onChange={(e)=>{
                setContent(e.target.value);
            }}
            
            />
        </div>
    </div>
    );
};

export default DiaryEditor;​

textarea도 input와 동일한 방식으로 처리할 수 있다. 그래서 input과 똑같이 State 처리를 해주면 된다. input의 State와 textarea의 State와 동일하게 동작하며 코드도 똑같다. 이렇게 비슷하게 동작하는 State는 하나로 합칠 수도 있다.

 

import {useState} from "react";

const DiaryEditor = () => {

    const [state, setState] = useState({
        author:"",
        content:"",
        }
    );

    // const [author,setAuthor] = useState("");
    // const [content,setContent] = useState("");

    return (
    <div className='DiaryEditor'>
        <h2>오늘의 일기</h2>
        <div>
            <input value={state.author} 
            onChange={(e)=>{
                setState({
                    author:e.target.value,
                    content:state.content,
                });
            }}
            />
        </div>
        <div>
            <textarea valeu={state.content} 
            onChange={(e)=>{
                setState({
                    author:state.author,
                    conten:e.target.value,
                });
            }}
            />
        </div>
    </div>
    );
};

export default DiaryEditor;

input의 경우 author의 값은 변화되어야하고, content의 값은 원래 상태 값을 그대로 유지해야 한다. 그래서 state.content를 적어주면 된다. 그런데 state에 두 개의 상태 말고 10개의 상태가 존재하면 어떨까? 값이 변경되는 부분 말고는 다 현재의 상태를 유지시키기 위해 state.속성 이런 식으로 적었을 것이다. 이럴 땐 스프레드 연산자를 사용하면 불필요한 부분을 짧게 줄일 수 있다.

                setState({
                    ...state,
                    author:e.target.value,
                });

스프레드 연산자는 객체 안에 있는 속성들을 모두 펼쳐주는 연산자로 setState함수 안에서 사용하면 '속성 : state.속성' 상태로 모든 속성을 펼쳐줄 것이다. 그래서 변경될 속성만 따로 선언 후 코드를 작성하면 된다.

반응형

 

이번에는 중복되는 onChange 이벤트를 하나로 합쳐보자.

import {useState} from "react";

const DiaryEditor = () => {

    const [state, setState] = useState({
        author:"",
        content:"",
        }
    );


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

        setState({
            ...state,
            [e.target.name]: e.target.value,
        });
    }

    return (
    <div className='DiaryEditor'>
        <h2>오늘의 일기</h2>
        <div>
            <input name="author" value={state.author} 
            onChange={handleChangeState}
            />
        </div>
        <div>
            <textarea name="content" valeu={state.content} 
            onChange={handleChangeState}
            />
        </div>
    </div>
    );
};

export default DiaryEditor;

 

마지막으로 나의 감정을 숫자로 표현할 수 있도록 셀렉트 박스와 저장할 수 있는 버튼을 만들자.

import {useState} from "react";

const DiaryEditor = () => {

    const [state, setState] = useState({
        author:"",
        content:"",
        emotion:1,
        }
    );

    // const [author,setAuthor] = useState("");
    // const [content,setContent] = useState("");

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

        setState({
            ...state,
            [e.target.name]: e.target.value,
        });
    };

    const handleSubmit =(e) => {
        console.log(state);
        alert("저장 성공");
    }

    return (
    <div className='DiaryEditor'>
        <h2>오늘의 일기</h2>
        <div>
            <input name="author" value={state.author} 
            onChange={handleChangeState}
            />
        </div>
        <div>
            <textarea name="content" valeu={state.content} 
            onChange={handleChangeState}
            />
        </div>
        <div>
        <span>오늘의 감정 점수 :  </span>
            <select name='emotion' value={state.emotion} onChange={handleChangeState}>
                <option value={1}>1</option>
                <option value={2}>2</option>
                <option value={3}>3</option>
                <option value={4}>4</option>
                <option value={5}>5</option>
            </select>
        </div>
        <div>
            <button onClick={handleSubmit}>
                일기 저장하기
            </button>
        </div>
    </div>
    );
};

export default DiaryEditor;

 

그리고 CSS를 적용해준다.

App.css

.DiaryEditor{
    border: 1px solid gray;
    text-align: center;
    padding : 20px;
}

.DiaryEditor input, textarea {
    margin-bottom: 20px;
    width : 500px;
    padding: 10px;
}

.DiaryEditor textarea {
    height : 150px;
}

.DiaryEditor select {
    width: 300px;
    padding: 10px;
    margin-bottom : 20px;
}

.DiaryEditor button {
    width: 500px;
    padding : 10px;
    cursor: pointer;
}

 

반응형
저작자표시 비영리 변경금지 (새창열림)
'공부/React.js' 카테고리의 다른 글
  • VSCode Prettier 자동 포맷팅 설정 방법, 설치 후 자동 정렬이 되지 않을 때
  • [React.js] React에서 DOM 조작하기
  • [React.js] Props
  • [React.js] State(상태), Counter 예제 만들기
데부한
데부한
어차피 할 거면 긍정적으로 하고 싶은 개발자
    반응형
  • 데부한
    동동이개발바닥
    데부한
  • 전체
    오늘
    어제
    • 분류 전체보기 (307)
      • 방통대 컴퓨터과학과 (27)
        • 잡담 (9)
        • 3학년1학기 (17)
      • 프로젝트 및 컨퍼런스 회고 (1)
        • 프로젝트 (4)
        • 한이음 프로젝트 (0)
        • 회고 (3)
      • 공부 (165)
        • Spring (37)
        • JPA (71)
        • 인프런 워밍업 클럽_BE (10)
        • Java (6)
        • React.js (27)
        • 넥사크로 (11)
        • 기타 (3)
      • 알고리즘 (85)
        • 알고리즘 유형 (10)
        • 알고리즘 풀이 (57)
        • SQL 풀이 (18)
      • 에러 해결 (13)
      • 잡담 (7)
        • 국비교육 (2)
        • 구매후기 (5)
        • 진짜 잡담 (0)
  • 블로그 메뉴

    • Github
    • Linkedin
    • 홈
    • 방명록
    • 글쓰기
    • 관리
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    백준
    IT
    springboot
    RESTful
    넥사크로
    에러해결
    Java
    QueryDSL
    기출문제
    운영체제
    전자정부프레임워크
    SpringBoot를 이용한 RESTful Web Service 개발
    방통대
    JPA
    react
    코딩테스트
    oracle
    자바스크립트
    egov
    토이프로젝트
    프로그래머스
    개발자
    프론트엔드
    토비의스프링부트
    MSA
    Spring
    스프링부트
    알고리즘
    인프런
    SQL
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
데부한
[React.js] React에서 사용자 입력 처리하기
상단으로

티스토리툴바