New페이지 뒤로가기 버튼 활성화
New.js
import Header from "../components/Header";
import Button from "../components/Button";
import Editor from "../components/Editor";
import { useNavigate } from "react-router-dom";
const New = () => {
const nav = useNavigate();
return (
<div>
<Header
title='새 일기 쓰기'
leftChild={ <Button text={'< 뒤로 가기'} onClick={() => nav(-1)}/>}
/>
<Editor/>
</div>
)
}
export default New;
오늘의 날짜 및 입력창 활성화
New.js
import Header from "../components/Header";
import Button from "../components/Button";
import Editor from "../components/Editor";
import { useNavigate } from "react-router-dom";
import { useContext } from "react";
import { DiaryDispatchContext } from "../App";
const New = () => {
const { onCreate } = useContext(DiaryDispatchContext);
const nav = useNavigate();
const onSubmit = (input) => {
onCreate(
input.createdDate.getTime(),
input.emotionId,
input.content
);
}
return (
<div>
<Header
title='새 일기 쓰기'
leftChild={ <Button text={'< 뒤로 가기'} onClick={() => nav(-1)}/>}
/>
<Editor onSubmit={onSubmit}/>
</div>
)
}
export default New;
Editor.js
import './Editor.css'
import EmotionItem from './EmotionItem';
import Button from './Button';
import { useState } from 'react';
const emotionList = [{
emotionId: 1,
emotionName: '매우 좋음'
},
{
emotionId:2,
emotionName: '좋음'
},
{
emotionId:3,
emotionName: '보통'
},
{
emotionId:4,
emotionName: '나쁨'
},
{
emotionId:5,
emotionName: '매우나쁨'
},
]
const Editor = ({onSubmit}) => {
const [input, setInput] = useState({
createdDate: new Date(),
emotionId: 3,
content: ""
})
const onChangeInput = (e) => {
let name= e.target.name;
let value= e.target.value;
console.log(name);
console.log(value);
}
const emotionId = 5;
return (
<div className='Editor'>
<section className='date_section'>
<h4>오늘의 날짜</h4>
<input
type='date'
name='createdDate'
onChange={onChangeInput}
value={input.createdDate}
/>
</section>
<section className='emotion_section'>
<h4>오늘의 감정</h4>
<div className='emotion_list_wrapper'>
{emotionList.map((item) => (
<EmotionItem
key={item.emotionId}
{...item}
isSelected={item.emotionId === emotionId}
/>
))}
</div>
</section>
<section className='content_section'>
<h4>오늘의 일기</h4>
<textarea
placeholder='오늘은 어땠나요?'
name='content'
onChange={onChangeInput}
/>
</section>
<section className='button_section'>
<Button text={'취소하기'}/>
<Button text={'작성완료'} type='POSITIVE'/>
</section>
</div>
)
}
export default Editor;
현재 결과

날짜 입력된거 띄우기
Editor.js
import './Editor.css'
import EmotionItem from './EmotionItem';
import Button from './Button';
import { useState } from 'react';
const emotionList = [{
emotionId: 1,
emotionName: '매우 좋음'
},
{
emotionId:2,
emotionName: '좋음'
},
{
emotionId:3,
emotionName: '보통'
},
{
emotionId:4,
emotionName: '나쁨'
},
{
emotionId:5,
emotionName: '매우나쁨'
},
]
const getStringDate = (targetDate) => {
// yyyy-mm-dd
let year = targetDate.getFullYear();
let month = targetDate.getMonth() +1
let date = targetDate.getDate();
if (month < 10){
month = `0${month}`;
}
if (date < 10){
date = `0${date}`;
}
return `${year}-${month}-${date}`;
}
const Editor = ({onSubmit}) => {
const [input, setInput] = useState({
createdDate: new Date(),
emotionId: 3,
content: ""
})
const onChangeInput = (e) => {
let name= e.target.name;
let value= e.target.value;
if(name ==='createdDate'){
value = new Date(value);
}
setInput({
...input,
[name]: value
})
}
const emotionId = 5;
return (
<div className='Editor'>
<section className='date_section'>
<h4>오늘의 날짜</h4>
<input
type='date'
name='createdDate'
onChange={onChangeInput}
value={getStringDate(input.createdDate)}
/>
</section>
<section className='emotion_section'>
<h4>오늘의 감정</h4>
<div className='emotion_list_wrapper'>
{emotionList.map((item) => (
<EmotionItem
key={item.emotionId}
{...item}
isSelected={item.emotionId === emotionId}
/>
))}
</div>
</section>
<section className='content_section'>
<h4>오늘의 일기</h4>
<textarea
placeholder='오늘은 어땠나요?'
name='content'
onChange={onChangeInput}
/>
</section>
<section className='button_section'>
<Button text={'취소하기'}/>
<Button text={'작성완료'} type='POSITIVE'/>
</section>
</div>
)
}
export default Editor;
현재 결과

사진 클릭시 바꾸기
Editor.js
import './Editor.css'
import EmotionItem from './EmotionItem';
import Button from './Button';
import { useState } from 'react';
const emotionList = [{
emotionId: 1,
emotionName: '매우 좋음'
},
{
emotionId:2,
emotionName: '좋음'
},
{
emotionId:3,
emotionName: '보통'
},
{
emotionId:4,
emotionName: '나쁨'
},
{
emotionId:5,
emotionName: '매우나쁨'
},
]
const getStringDate = (targetDate) => {
// yyyy-mm-dd
let year = targetDate.getFullYear();
let month = targetDate.getMonth() +1
let date = targetDate.getDate();
if (month < 10){
month = `0${month}`;
}
if (date < 10){
date = `0${date}`;
}
return `${year}-${month}-${date}`;
}
const Editor = ({onSubmit}) => {
const [input, setInput] = useState({
createdDate: new Date(),
emotionId: 3,
content: ""
})
const onChangeInput = (e) => {
let name= e.target.name;
let value= e.target.value;
if(name ==='createdDate'){
value = new Date(value);
}
setInput({
...input,
[name]: value
})
}
//const emotionId = 5;
const onSubmitButtonClick = () => {
onSubmit(input);
}
return (
<div className='Editor'>
<section className='date_section'>
<h4>오늘의 날짜</h4>
<input
type='date'
name='createdDate'
onChange={onChangeInput}
value={getStringDate(input.createdDate)}
/>
</section>
<section className='emotion_section'>
<h4>오늘의 감정</h4>
<div className='emotion_list_wrapper'>
{emotionList.map((item) => (
<EmotionItem
onClick={() =>
onChangeInput({
target: {
name: 'emotionId',
value: item.emotionId
}}
)
}
key={item.emotionId}
{...item}
isSelected={item.emotionId === input.emotionId}
/>
))}
</div>
</section>
<section className='content_section'>
<h4>오늘의 일기</h4>
<textarea
placeholder='오늘은 어땠나요?'
name='content'
onChange={onChangeInput}
/>
</section>
<section className='button_section'>
<Button text={'취소하기'}/>
<Button
text={'작성완료'}
type='POSITIVE'
onClick={onSubmitButtonClick}
/>
</section>
</div>
)
}
export default Editor;
EmotionItem,js
.Editor > section {
margin-bottom: 40px;
}
.Editor > section > h4 {
font-size: 22px;
font-weight: bold;
}
.Editor > section > input, textarea{
background-color: rgb(236, 236, 236);
border : none;
border-radius: 5px;
font-size: 20px;
padding: 10px 20px ;
}
.Editor > section > textarea{
padding: 20px;
width: 100%;
min-height: 200px;
resize: vertical;
box-sizing: border-box;
}
.Editor .emotion_section .emotion_list_wrapper{
display: flex;
justify-content: space-around;
gap: 2%;
}
.Editor .button_section{
display: flex;
justify-content: space-between;
}
New.js
import Header from "../components/Header";
import Button from "../components/Button";
import Editor from "../components/Editor";
import { useNavigate } from "react-router-dom";
import { useContext } from "react";
import { DiaryDispatchContext } from "../App";
const New = () => {
const { onCreate } = useContext(DiaryDispatchContext);
const nav = useNavigate();
const onSubmit = (input) => {
onCreate(
input.createdDate.getTime(),
input.emotionId,
input.content
);
nav('/', {replace: true}); //replac true 뒤로가기 막기
}
return (
<div>
<Header
title='새 일기 쓰기'
leftChild={ <Button text={'< 뒤로 가기'} onClick={() => nav(-1)}/>}
/>
<Editor onSubmit={onSubmit}/>
</div>
)
}
export default New;
Editor.js
import './Editor.css'
import EmotionItem from './EmotionItem';
import Button from './Button';
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
const emotionList = [{
emotionId: 1,
emotionName: '매우 좋음'
},
{
emotionId:2,
emotionName: '좋음'
},
{
emotionId:3,
emotionName: '보통'
},
{
emotionId:4,
emotionName: '나쁨'
},
{
emotionId:5,
emotionName: '매우나쁨'
},
]
const getStringDate = (targetDate) => {
// yyyy-mm-dd
let year = targetDate.getFullYear();
let month = targetDate.getMonth() +1
let date = targetDate.getDate();
if (month < 10){
month = `0${month}`;
}
if (date < 10){
date = `0${date}`;
}
return `${year}-${month}-${date}`;
}
const Editor = ({onSubmit}) => {
const nav = useNavigate();
const [input, setInput] = useState({
createdDate: new Date(),
emotionId: 3,
content: ""
})
const onChangeInput = (e) => {
let name= e.target.name;
let value= e.target.value;
if(name ==='createdDate'){
value = new Date(value);
}
setInput({
...input,
[name]: value
})
}
//const emotionId = 5;
const onSubmitButtonClick = () => {
onSubmit(input);
}
return (
<div className='Editor'>
<section className='date_section'>
<h4>오늘의 날짜</h4>
<input
type='date'
name='createdDate'
onChange={onChangeInput}
value={getStringDate(input.createdDate)}
/>
</section>
<section className='emotion_section'>
<h4>오늘의 감정</h4>
<div className='emotion_list_wrapper'>
{emotionList.map((item) => (
<EmotionItem
onClick={() =>
onChangeInput({
target: {
name: 'emotionId',
value: item.emotionId
}}
)
}
key={item.emotionId}
{...item}
isSelected={item.emotionId === input.emotionId}
/>
))}
</div>
</section>
<section className='content_section'>
<h4>오늘의 일기</h4>
<textarea
placeholder='오늘은 어땠나요?'
name='content'
onChange={onChangeInput}
/>
</section>
<section className='button_section'>
<Button text={'취소하기'} onClick={() => nav(-1)}/>
<Button
text={'작성완료'}
type='POSITIVE'
onClick={onSubmitButtonClick}
/>
</section>
</div>
)
}
export default Editor;
이모션 코드 따로 구성하기

Editor.js
import './Editor.css'
import EmotionItem from './EmotionItem';
import Button from './Button';
import { useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { emotionList } from '../util/constants';
수정하기 버튼
Edit.js
import { useParams, useNavigate } from "react-router-dom";
import Header from "../components/Header";
import Editor from "../components/Editor";
import Button from "../components/Button";
const Edit = () => {
const params = useParams();
const nav = useNavigate();
return (
<div>
<Header
title={'일기 수정하기'}
leftChild={
<Button onClick = {() => nav(-1)} text={'< 뒤로가기'} />
}
rightChild={
<Button
text={'삭제하기'}
type={'NEGATIVE'}
/>
}
/>
<Editor/>
</div>
)
}
export default Edit;
현재 결과

App.js
import './App.css';
import Diary from './pages/Diary';
import New from './pages/New';
import Home from './pages/Home';
import Notfound from './pages/Notfound';
import { Route, Routes } from 'react-router-dom';
import { useReducer, useRef, createContext } from 'react';
import Header from './components/Header';
import Button from './components/Button';
import Edit from './pages/Edit';
const mockData = [
{
id: 1,
createdDate: new Date('2025-09-09').getTime(),
emotionId: 1,
content:'1번 일기 내용'
},
{
id: 2,
createdDate: new Date('2025-09-03').getTime(),
emotionId: 2,
content: '2번 일기 내용'
},
{
id: 3,
createdDate: new Date('2025-08-22').getTime(),
emotionId: 4,
content: '3번 일기 내용'
}
]
function reducer(state, action){
console.log(action)
switch(action.type){
case 'CREATE':
return [action.data, ...state]
case 'UPDATE':
return state.map((item) =>
String(item.id) === String(action.data.id) ? action.data : item
)
case 'DELETE':
return state.filter(
(item) => String(item.id) !== String(action.id)
);
default:
return state;
}
}
export const DiaryStateContext = createContext();
export const DiaryDispatchContext = createContext();
function App() {
const [data, dispatch] = useReducer(reducer, mockData);
const idRef = useRef(4);
const onCreate = (createdDate, emotionId, content) => {
dispatch({
type: 'CREATE',
data: {
id: idRef.current++,
createdDate,
emotionId,
content
}
})
}
const onUpdate = (id, createdDate, emotionId, content) => {
dispatch({
type:'UPDATE',
data: {
id,
createdDate,
emotionId,
content
}
})
}
const onDelete = (id) => {
dispatch({
type:'DELETE',
id
})
}
return (
<>
<DiaryStateContext.Provider value={data}>
<DiaryDispatchContext.Provider value={{ onCreate, onUpdate, onDelete}}>
<Routes>
<Route path='/' element={ <Home/> }/>
<Route path='/new' element={ <New/> }/>
<Route path='/diary/:id' element={ <Diary/> }/>
<Route path='/edit/:id' element={ <Edit/> }/>
<Route path='*' element={ <Notfound/> }/>
</Routes>
</DiaryDispatchContext.Provider>
</DiaryStateContext.Provider>
</>
);
}
export default App;
Edit.js
import { useParams, useNavigate } from "react-router-dom";
import Header from "../components/Header";
import Editor from "../components/Editor";
import Button from "../components/Button";
import { DiaryStateContext, DiaryDispatchContext } from "../App";
import { useContext, useEffect, useState } from "react";
const Edit = () => {
const params = useParams();
const nav = useNavigate();
const data = useContext(DiaryStateContext);
const { onUpdate } = useContext(DiaryDispatchContext);
const [curDiaryItem, setCurDiaryItem] = useState();
useEffect(() => {
const currentDiaryItem = data.find(
(item) => String(item.id) === String(params.id)
);
if(!currentDiaryItem) {
window.alert('존재하지 않은 일기입니다.');
nav('/', {replace: true})
}
setCurDiaryItem(currentDiaryItem);
console.log(currentDiaryItem);
}, [params.id, data])
const onSubmit = (input) => {
onUpdate(
params.id,
input.createdDate.getTime(),
input.emotionId,
input.content
)
nav('/', {replac : true});
}
return (
<div>
<Header
title={'일기 수정하기'}
leftChild={
<Button onClick = {() => nav(-1)} text={'< 뒤로가기'} />
}
rightChild={
<Button
text={'삭제하기'}
type={'NEGATIVE'}
/>
}
/>
<Editor initData={curDiaryItem} onSubmit={onSubmit}/>
</div>
)
}
export default Edit;
Editor.js
import './Editor.css'
import EmotionItem from './EmotionItem';
import Button from './Button';
import { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import { emotionList } from '../util/constants';
const getStringDate = (targetDate) => {
// yyyy-mm-dd
let year = targetDate.getFullYear();
let month = targetDate.getMonth() +1
let date = targetDate.getDate();
if (month < 10){
month = `0${month}`;
}
if (date < 10){
date = `0${date}`;
}
return `${year}-${month}-${date}`;
}
const Editor = ({initData, onSubmit}) => {
const nav = useNavigate();
const [input, setInput] = useState({
createdDate: new Date(),
emotionId: 3,
content: ""
})
useEffect(()=> {
if(initData){
setInput({
...initData,
createdDate: new Date(Number(initData.createdDate))
})
}
}, [initData])
const onChangeInput = (e) => {
let name= e.target.name;
let value= e.target.value;
if(name ==='createdDate'){
value = new Date(value);
}
setInput({
...input,
[name]: value
})
}
//const emotionId = 5;
const onSubmitButtonClick = () => {
onSubmit(input);
}
return (
<div className='Editor'>
<section className='date_section'>
<h4>오늘의 날짜</h4>
<input
type='date'
name='createdDate'
onChange={onChangeInput}
value={getStringDate(input.createdDate)}
/>
</section>
<section className='emotion_section'>
<h4>오늘의 감정</h4>
<div className='emotion_list_wrapper'>
{emotionList.map((item) => (
<EmotionItem
onClick={() =>
onChangeInput({
target: {
name: 'emotionId',
value: item.emotionId
}}
)
}
key={item.emotionId}
{...item}
isSelected={item.emotionId === input.emotionId}
/>
))}
</div>
</section>
<section className='content_section'>
<h4>오늘의 일기</h4>
<textarea
placeholder='오늘은 어땠나요?'
name='content'
onChange={onChangeInput}
value={input.content}
/>
</section>
<section className='button_section'>
<Button text={'취소하기'} onClick={() => nav(-1)}/>
<Button
text={'작성완료'}
type='POSITIVE'
onClick={onSubmitButtonClick}
/>
</section>
</div>
)
}
export default Editor;
New.js
import Header from "../components/Header";
import Button from "../components/Button";
import Editor from "../components/Editor";
import { useNavigate } from "react-router-dom";
import { useContext } from "react";
import { DiaryDispatchContext } from "../App";
const New = () => {
const { onCreate } = useContext(DiaryDispatchContext);
const nav = useNavigate();
const onSubmit = (input) => {
onCreate(
input.createdDate.getTime(),
input.emotionId,
input.content
);
nav('/', {replace: true}); //replac true 뒤로가기 막기
}
return (
<div>
<Header
title='새 일기 쓰기'
leftChild={ <Button text={'< 뒤로 가기'} onClick={() => nav(-1)}/>}
/>
<Editor onSubmit={onSubmit}/>
</div>
)
}
export default New;
현재 결과

수정시 알림창 띄우기
Edit.js
import { useParams, useNavigate } from "react-router-dom";
import Header from "../components/Header";
import Editor from "../components/Editor";
import Button from "../components/Button";
import { DiaryStateContext, DiaryDispatchContext } from "../App";
import { useContext, useEffect, useState } from "react";
const Edit = () => {
const params = useParams();
const nav = useNavigate();
const data = useContext(DiaryStateContext);
const { onUpdate } = useContext(DiaryDispatchContext);
const [curDiaryItem, setCurDiaryItem] = useState();
useEffect(() => {
const currentDiaryItem = data.find(
(item) => String(item.id) === String(params.id)
);
if(!currentDiaryItem) {
window.alert('존재하지 않은 일기입니다.');
nav('/', {replace: true})
}
setCurDiaryItem(currentDiaryItem);
console.log(currentDiaryItem);
}, [params.id, data])
const onSubmit = (input) => {
if (window.confirm('일기를 정말로 수정하시겠습니까?')){
onUpdate(
params.id,
input.createdDate.getTime(),
input.emotionId,
input.content
)
nav('/', {replac : true});
}
}
return (
<div>
<Header
title={'일기 수정하기'}
leftChild={
<Button onClick = {() => nav(-1)} text={'< 뒤로가기'} />
}
rightChild={
<Button
text={'삭제하기'}
type={'NEGATIVE'}
/>
}
/>
<Editor initData={curDiaryItem} onSubmit={onSubmit}/>
</div>
)
}
export default Edit;
현재 결과

'Front > React' 카테고리의 다른 글
| Day13_react(7)_Pm (0) | 2025.09.12 |
|---|---|
| Day11_react(6)_Am (0) | 2025.09.10 |
| Day11_react(6)_Am (0) | 2025.09.09 |
| Day10_react(5)_Pm (0) | 2025.09.08 |
| Day10_react(5)_Am (0) | 2025.09.08 |