[Udemy] React 기본 - 일기장 만들기(1)
React 기본 (Project)
Udemy - 한입크기로 잘라 먹는 리액트
📌 일기장 만들기 (1)
src/App.js
import "./App.css";
import DiaryEditor from "./DiaryEditor";
const App = () => {
return (
<div className="App">
<DiaryEditor />
</div>
);
};
export default App;
src/DiaryEditor.js
☑️ DiaryEditor : 일기장 컴포넌트
- 클래스의 네임을 컴포넌트의 네임과 일치 (직관적인 스타일 코드 작성)
- 작성자(input), 일기 본문(textarea), 감정점수(select), 저장하기(button)
☑️ useState : 요소를 리액트가 직접 핸들링할 수 있도록 만들어야 함
☑️ 상태변화 함수 : input과 textarea가 받는 value prop으로 전달
-
useState("작성자"); : 초기값 설정
-
onChange
값이 실시간으로 바뀌도록 이벤트 설정(콜백함수 등록하여 event 객체인 e를 매개변수로 전달받게 됨)
사용자가 입력을 하면 어떤 사건이 발생했다고 인식하는데 onChange는 값이 바뀌었을 때 수행하는 이벤트
= input에 값이 바뀌었을 때 onChange의 Prop에 전달한 콜백함수를 수행한다라고 생각하면 됨 -
e.target.value
console을 통해 전달받은 이벤트 객체를 열어보면 target을 키를 열면 지금 바뀐 value 확인 가능
이벤트 객체의 target의 value를 이용하면 입력하고 있는 값을 콜백함수에 불러서 사용 가능
input이 변화해야 하는 값 -
setAuthor(e.target.value), setContent(e.target.value)
작성자 input이 변화해야 하는 값이 변화할 때마다 그 값으로 업데이트 시키면 state와 함께 input을 이용할 수 있게 됨
콜백함수가 수행될 때 매개변수인 이벤트 객체 e에서 지금 현재 입력받은(지금 현재 변화한) 값을 새로운 상태의 값으로 변화시키면서 author, content state가 바뀌어서 value가 바뀌고 실제로 화면에 렌더링된다.
const [author, setAuthor] = useState("");
const [content, setContent] = useState("");
<input name="author" value={author}
onChange={ (e) => {setAuthor(e.target.value);}
} />
<textarea name="content" value={content}
onChange={ (e) => {setContent(e.target.value);}
} />
☑️ 동일한 state (value, onChange의 콜백함수, 자료형(공백문자열)) 라면 하나의 state로 묶을 수 있다.
- state가 author와 content를 같이 갖고 있는 배열
- 새로운 객체를 만들어서 전달해줘야 함 (상태를 변화시킬 때는 setState 상태변화 함수에 새로 변경시킬 값을 인자로 전달해줬었기 때문) = 객체의 값을 바꾸려면 새로운 객체를 만들어서 전달해줘야 함
- input에서 author는 e.target.value로 바뀌어야 하지만 content는 변하면 안됨(유지해야하므로) 원래있던 state로 업데이트를 해준다. (textarea에서는 content가 바뀌고 author가 유지)
const [state, setState] = useState({
author: "",
content: "",
});
<input name="author" value={state.author}
onChange={ (e) => {
setState({
author: e.target.value,
content: state.content,
});
}
} />
<textarea name="content" value={state.content}
onChange={ (e) => {
setState({
content: e.target.value,
author: state.author,
});
}
} />
☑️ spread 연산자 활용
- 객체로 state를 합쳤는데 만약 여러개로 값이 많을 경우
- state가 가지고 있는 properties을 펼쳐줌
- setState로 전달되서 새로운 객체를 만들 때 author: e.target.value에 새로 값이 들어왔을 건데, 다음 줄에 spread 연산자가 오게 되면 author의 값이 또 들어오게 됨 (원래의 값으로 덮어씌워지게 되면 결론적으로 아무 것도 업데이트가 안되게 됨) =>
원래있던 state를 먼저 펼쳐주고 나서 변경하고자하는 state의 property를 마지막에 적어준다
const [state, setState] = useState({
author: "",
content: "",
});
<input name="author" value={state.author}
onChange={ (e) => {
setState({
...state,
author: e.target.value,
});
}
} />
<textarea name="content" value={state.content}
onChange={ (e) => {
setState({
...state,
content: e.target.value,
});
}
} />
☑️ 중복코드 제거 - eventHandler 합치기
- input과 textarea에 들어갈 onChange의 eventHandler
- name과 value : 바뀐 값으로 자동 업데이트
const handleChangeState = (e) => {
setState({
...state,
[e.target.name]: e.target.value,
});
};
<input name="author" value={state.author} onChange={handleChangeState} />
<textarea name="content" value={state.content} onChange={handleChangeState} />
☑️ 감정점수 1~5점으로 표시 (select, option)
- 문자열이 아니므로 기본값을 1로 넣어줌
- name, value, onChange 똑같이 넣어줌
- emotion property는 select가 다른 걸 고르게 되면 onChange 이벤트가 발생 => handleChangeState 실행 => e.targer.name의 emotion의 값이 변하고 => 옵션이 바뀐다
const [state, setState] = useState({
author: "",
content: "",
emotion: 1,
});
<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>
☑️ 저장하기 (button)
- 버튼 누르면 alert창
const handleSubmit = () => {
console.log(state);
alert("저장 성공!");
};
<button onClick={handleSubmit}>일기 저장하기</button>
☑️ CSS styling
.App {margin:0 auto;}
.DiaryEditor { border:1px solid #e5e5e5; text-align:center; padding: 20px; }
.DiaryEditor input, .DiaryEditor textarea { margin:0 0 20px 0; padding:10px; width:500px; }
.DiaryEditor textarea { width:500px; height:150px; }
.DiaryEditor select { margin:0 0 20px 0; padding:10px; width:500px; }
.DiaryEditor button { cursor:pointer; padding:10px; width:500px; }
📝 Result
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
value={state.author}
onChange={handleChangeState}
name="author"
placeholder="작성자"
type="text"
/>
</div>
<div>
<textarea
value={state.content}
onChange={handleChangeState}
name="content"
placeholder="일기"
type="text"
/>
</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;
Author And Source
이 문제에 관하여([Udemy] React 기본 - 일기장 만들기(1)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@productuidev/Udemy-React-기본-일기장-만들기1저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)