React 사용자 입력 처리하기

Sujeong K·2022년 9월 6일
0

React

목록 보기
2/5

📌 입력받은 값을 추후 사용할 수 있도록 useState를 이용해 저장해보자

작성자 이름 입력받기

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;

*class 이름 = 컴포넌트 이름 : 나중에 class를 이용해서 css로 스타일링 할 때 직관적으로 보기 위해(참고용 방법!)

  • input의 value를 state로 설정했을 때
    : 해당 state는 setAuthor 함수로만 변경될 수 있기 때문에 input이 변경될 때 setAuthor 함수를 이용해서 입력한 값이 input에 보이도록 해줘야함.

➡️ onChange 속성 사용하기

    return <div className="DiaryEditor">
        <h2>오늘의 일기</h2>
        <div>
            <input value={author} onChange={(e)=>{
                console.log(e);
            }}/>
        </div>
    </div>;
  • input 태그에 Change 이벤트가 발생하면 콜백함수 {(e)=>{ console.log(e); }}를 실행하도록 명령
  • input에 값을 입력할 때마다 event 객체에 대한 정보 출력됨
  • event 객체의 target-value를 이용해서 input의 값 변경 가능
    return <div className="DiaryEditor">
        <h2>오늘의 일기</h2>
        <div>
            <input value={author} onChange={(e)=>{
                setAuthor(e.target.value);
            }}/>
        </div>
    </div>;
  • input 태그에 Change 이벤트가 발생하면 author의 값을 e.target.value로 변경
    (setAuthor를 사용해 input에 입력한 값으로 author 값을 업데이트)

작성자 이름 입력하는 input과 일기 내용 입력하는 textarea는 동작 방식이 동일
: value={state}, setState 함수를 이용해 event.target.value로 state 변경, 자료형은 문자열

✍ 동작이 비슷한 state 하나로 묶어주기

const DiaryEditor = () => {
    const [state, setState] = useState(
        {
            author:"",
            contents:"",
        } 
    )

    return <div className="DiaryEditor">
        <h2>오늘의 일기</h2>
        <div>
            <input value={state.author} onChange={(e)=>{
                setState({
                    author: e.target.value,
                    contents:state.contents,
                });
            }}/>
        </div>
        <div>
            <textarea value={state.contents} onChange={(e)=>{
                setState({
                    author: state.author,
                    contents: e.target.value,
                })}}/> 
        </div>
    </div>;
}; 
  • state의 초기값을 객체로 만들어줌
  • 각 target에 onChange 이벤트 발생 => setState 콜백함수 실행 => 각각 event.target.value로 변경할 state 업데이트(자신의 change가 아닌 경우는 원래 값으로 고정) => state.author 혹은 state.contents로 value 변경

✍ 만약 입력창이 2개가 아니라 10개였다면..?

const DiaryEditor = () => {
    const [state, setState] = useState(
        {
            author:"",
            contents:"",
        }
    )

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

📌 Spread 연산자로 state 객체를 펼친 후 업데이트 할 state의 property만 써주기

...state를 업데이트 할 속성 뒤에 쓴다면?

setState({
author: e.target.value,
...state,
     });
  • author 값 변경 후 state 객체 펼쳐짐 => 원래 state 객체에 있던 state.author 값으로 author 값이 다시 변경 => 업데이트 안됨

✍ onChange에 전달할 함수도 하나로 합쳐보자

const DiaryEditor = () => {
    const [state, setState] = useState(
        {
            author:"",
            contents:"",
        }
    )

    const handleChangeState = (e) => {
        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="contents" value={state.contents} onChange={handleChangeState}/> 
        </div>
    </div>;
}; // 각 입력창에 name 추가해줌
  • e.target.name은 각 입력창의 이름이자 state 객체의 속성의 key값
  • 각 target에 onChange 이벤트 발생 => handleChangeState 함수 실행 =>
    원래 state 객체 펼치고 [e.target.name] : e.target.value 변경
    *[e.target.name]은 객체의 괄호 표기법

✍ 감정 점수도 같은 이벤트 핸들러로 만들어주기

    return <div className="DiaryEditor">
        <h2>오늘의 일기</h2>
        <div>
            <input name="author" value={state.author} onChange={handleChangeState}/>
        </div>
        <div>
            <textarea name="contents" value={state.contents} onChange={handleChangeState}/> 
        </div>
        <div>
        <label>오늘의 감정점수 : </label>
            <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>;

Studying...

https://inf.run/qAuJ
한입 크기로 잘라 먹는 리액트(React.js) : 기초부터 실전까지 by 이정환 Winterlood

profile
차근차근 천천히

0개의 댓글