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등 코드,값(자료형="")까지 동일한것을 볼 수 있다.
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태그를 이용하여 감정상태와 저장하기를 추가로 작성하였다.
저장을 하면 위와같이 콘솔창에 찍히고 알람이 뜨는것을 확인 할 수 있다.
//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가 입려지는것을 확인할 수 있다.