[React] 사용자 입력 (feat.일기장)

Hyun·2022년 1월 4일
1

React

목록 보기
4/22
post-thumbnail

DiaryEditor컴퍼런트를 만들고 일기에 필요한 값들(작성자=author/내용=content)을 입력하기위해 react에 <input/>,<textarea/>태그를 입력하면 페이지에 입력란이 생성된다.

<input>태그 = 한줄만 입력할 수 있는 입력값
<textarea>태그 = 여러줄을 입력할 수 있는 입력값(늘였다 줄였다 할 수 있음)

여기서 입력된 값이 리액트가 핸들링할 수 있도록 (=diaryeditor컴퍼런트가 input에 작성된 값을 직접 핸들링할 수 있도록) 처리를 해야한다.
사용자의 입력을 리액트에서 이용하기위해서는 state를 이용할 수 있는데 useState를 이용하려면 위에 import {useState} from "react"; 를 입력하고 사용을 시작함을 알린다.

const [state, setState] = useState("");
앞서 state 사용하는것을 배웠다.
복습하자면 첫번째값은 입력하는현재상태 / 두번째값은 현재상태를 변화시키는 상태변화함수 / useState("초기값") 이다.
🔥state는 setState가 없으면 절대로 상태를 변화시킬 수가 없다.
그래서 변화가 일어났을때 setState를 수행하라는 명시가 없으면 자동으로 상태가 변화하지않아서 state는 변화하지않는다.

현재 필요한 입력값은 작성자=author/내용=content이고 각각 const [author, setAuthor] = useState(""); / const [content, setContent] = useState("");값을 가지는데, 여기에 변화가 생기면 setAuthor,setContent 를 실행하라고 명시해야하기 onChange이벤트를 사용한다.

onChange의 prop에 전달할것은 콜백함수를 전달을하고, 콜백함수에 매개변수로 e(이벤트객체)를 전달받게된다. 그 매개변수를 출력을해보면 input에 입력한 값들을 볼 수 있다.

<div>
<input value={author} 
 onChange={(e)=>{
 console.log(e);
 }}/>
</div>

<div>
<textarea  value={content} 
 onChange={(e)=>{
 console.log(e);
}}/>
</div>


아직 상태변화함수를 설정하지않아서 입력란에는 아무런 변화가 일어나지 않지만, 콘솔창으로 확인을해보면 target의 value에 변화가 일어나는것을 알 수 있다.

<div>
<input value={author} 
 onChange={(e)=>{
 console.log(e.target.value);
 }}/>
</div>

<div>
<textarea  value={content} 
 onChange={(e)=>{
 console.log(e.target.value);
}}/>
</div>


console.log(e.target.value);를 해보면 변화하는 값들을 볼 수 있다.
이 값은 author,content가 변화해야하는 값이므로 setAuthor,setContent에 입력을 해주자!

<div>
<input 
 value={author} 
 onChange={(e)=>{
 setAuthor(e.target.value);
 }}/>
</div>

<div>
<textarea  
 value={content} 
 onChange={(e)=>{
 setContent(e.target.value);
}}/>
</div>


setAuthor,satContent를 설정을 하니까 실시간으로 입력란이 입력되는것을 확인할 수 있다👍🏻
(*만약에 태그에 name도 있다면(<input name="author" value={author} onChange={(e)=>{setAuthor(e.target.value);}}/>) e.target.name으로 출력할수있다.)


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 
            value={content} 
            onChange={(e)=>{
                setContent(e.target.value);
            }}/>
        </div>
    </div>
};

export default DiaryEditor;

근데, 작성자와 내용의 state등 코드,값(자료형="")까지 동일한것을 볼 수 있다.

🌟state를 하나로 묶을 수 있다.

import { useState } from "react";

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

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

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

export default DiaryEditor;

비슷한 두개를 묶어 코드를 작성했지만, 비슷한게 10개 이상일경우에는 코드가 길어지기에

🌟스프레드연산자를 이용해서 작성하면 짧게 작성이 가능하다.

import { useState } from "react";

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

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

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

export default DiaryEditor;

...state가 의미하는 값은 author : "",content : ""이다.
💥여기서 스프레드연산자와 이벤트가일어나는값을 바꾸면 입력값이 바뀌지않는 현상이 일어나는데, 이유는 위에서 아래의 순서대로 업데이트가 되기때문이다.(즉, 실시간으로 바뀜이 일어나는데 초기값으로 재설정되는 상황)
원래있던 state를 펼쳐주고, 변경하고자하는 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);
    }

    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;


콘솔창에 위와같이 변화되는 값을 출력할 수 있다.

import { useState } from "react";

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

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

export default DiaryEditor;


import { useState } from "react";

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

    const handleChangeState = (e)=>{
        setState({
        ...state,
        [e.target.name] : e.target.value,
    });
};
    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}>
                <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;

select태그와 button태그를 이용하여 감정상태와 저장하기를 추가로 작성하였다.

저장을 하면 위와같이 콘솔창에 찍히고 알람이 뜨는것을 확인 할 수 있다.


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

간단한 css가 입려지는것을 확인할 수 있다.

profile
FrontEnd Developer (with 구글신)

0개의 댓글