[React] 사용자 입력 처리하기

Hyoyoung Kim·2022년 8월 20일
1

React TIL

목록 보기
23/40

😎 일기장을 만들어보자~

내가 만들어야 하는 것

1. useState를 이용해서 '작성자 창'과 '일기 본문 창'을 만들어주자!

import React, {useState} from "react";


const DiaryEditor = () =>{

// input창(작성자 창)의 state
const [author, setAuthor] = useState("");

// textarea창(일기본문창)의 state
const [content, setContent] = useState("")

//작성자와 일기본문은 초기값은 입력을 안한 상태기에 공백으로 남겨준다. 


    return <div className="DiaryEditor">
        <h2>오늘의 일기</h2>
        
         <div>
            {/* 작성자 창 만들기 */}
            <input 
            value = {author}
            onChange={(e)=>{setAuthor(e.target.value)}}
            /> 
            {/* input의 value는 브라우저에 나타는 값 */}
            {/* onChange함수를 이용해 값이 변경될때마다 함수가 실행되면서 State에 지정한 함수가 실행 되도록 한다. */}
            {/* e는 이벤트 매개변수로 이벤트가 일어나면 여러 데이터를 가지고 있어, 
            e의 target을 이용해 어떤 것이 타켓 되었는지 판별하고 value의 값을 가져온다. */}
            {/* e.target.value : 이벤트가 벌어졌을 시점의 현재 입력값 (author가 변화해야하는 값)*/}
            {/* setAuthor(e.target.value) : 상태가 변화할떄마다(이벤트가 벌어질떄마다/입력할떄마다) 
            input창에 변화한 값을 직접적으로 입력할 수 있게 된다.  */}
         </div>

         <div>
            {/* 여러줄을 입력할 수 있는 '일기 본문'창 만들기 */}
            <textarea 
             value = {content}
             onChange={(e)=>{setContent(e.target.value)}}
            />
         </div>
    </div>
}

export default DiaryEditor;

2. (응용)중복된 State동작 정리해보자

작성자 창 state 동작과 일기본문 창 state 동작이 중복되니깐 정리하자

import React, {useState} from "react";


const DiaryEditor = () =>{

  // 하나의 useState로 합쳐준다.
    const [state , setState] = useState({
        author : "",
        content : ""
    })


    return <div className="DiaryEditor">
        <h2>오늘의 일기</h2>
        
         <div>
            {/* 작성자 창 만들기 */}
            <input 
            name ="author"
            value = {state.author}
            onChange={(e)=>{
                setState({
                    author : e.target.value,
                    content : state.content
                    // author의 값만 바뀌어야 하니깐 author은 이벤트가 벌어졌을 시점의 현재 입력값인 e.target.value을 입력해주고
                    // content는 지금 content의 현재값을 유지해주기 위해 state.content을 입력해준다. 
                })}}
            /> 
         </div>

         <div>
            {/* 여러줄을 입력할 수 있는 '일기 본문'창 만들기 */}
            <textarea 
            name ="content"
            value = {state.content}
            onChange={(e)=>{
                setState({
                    content : e.target.value,
                    author : state.author
                })}}
            />
         </div>
    </div>
}

export default DiaryEditor;

🎃spread를 이용한 다른 방식

 		<div>
            <input 
            value = {state.author}
            onChange = {(e)=>{
                setState({
                    ...state,
                  //...state를 펼쳐보면
                  // author : "",
       			  // content : ""
                  // 이 값이 나온다. 
                    author : e.target.value,
                  //그리고 author값에 e.target.value의 값을 다시 덧씌어준다.
                });
            }}
            />
        </div>

💢spread이용할 때 조심하자!

 		<div>
            <input 
            value = {state.author}
            onChange = {(e)=>{
                setState({
                  author : e.target.value,
                  ...state
                });
            }}
            />
        </div>

✔ 만약 이렇게 순서를 바꿔서 쓰게 된다면 author 값에 (author : e.target.value)을 넣어줬어도 코드 순서에 따라 다음에 오는 ...state에 의해 (author : "")의 값이 덧씌어져 입력창에 아무것도 안적힌다.
✔ 그래서 원래 있던 값인 ...state 를 먼저 펼쳐주고 나서 변경하고자 하는 값(author : e.target.value)을 나중에 적어주어야 한다.

3. 중복된 이벤트 핸들러 함수를 정리해보자!

import React, {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"
            value = {state.content}
            onChange={handleChangeState}
            />
         </div>
    </div>
}

export default DiaryEditor;

위의 사진을 보면 textarea창에 입력했을시 콘솔창에 name으로 content가 찍히고 value로 입력한 값이 찍힌다.

위 코드에서 이부분을 좀 더 자세히 보자면

   const handleChangeState = (e)=> {
        console.log(e.target.name);
        console.log(e.target.value)
        setState({
            ...state,
            [e.target.name] : e.target.value
          //그렇게에 내가 input창을 누루는 이벤트가 실행되면 저절로 [e.target.name]의 값에는 'author'값이 들어가고
          // e.target.value의 값에는 현재 input창에 입력된 값이 들어간다.
        })
    }

4. '감정점수'와 '저장하기 버튼'을 한번 만들어 볼까?

import React, {useState} from "react";


const DiaryEditor = () =>{

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

    const handleChangeState = (e)=> {
        console.log(e.target.name);
        console.log(e.target.value)
        setState({
            ...state,
            [e.target.name] : e.target.value
        })
    }

    // 저장버튼 onclick함수
    const handleSubmit = () => {
        console.log(state);
        alert("저장성공")
    }


    return <div className="DiaryEditor">
        <h2>오늘의 일기</h2>
        
         <div>
            {/* 작성자 창 만들기 */}
            <input 
            name ="author"
            value = {state.author}
            onChange={handleChangeState}
            /> 
         </div>

         <div>
            {/* 여러줄을 입력할 수 있는 '일기 본문'창 만들기 */}
            <textarea 
            name ="content"
            value = {state.content}
            onChange={handleChangeState}
            />
         </div>

         <div>
            {/* 감정점수 창 만들기 */}
 			 오늘의 감정점수 : 
            <select
                 name ="emotion"
                 value = {state.emotion}
                 onChange={handleChangeState}
                 >
                {/* select : 1에서 5까지 선택하는 태그 */}
                 <option value = {1}>1</option>
                 {/* option : select태그에서 선택할 수 있는 옵션 */}
                 <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;


✨ alert는?

메세지창 띄우기

5. 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;
}

0개의 댓글