Header 꾸미기
Header.js
import './Header.css'
const Header = ({title, leftChild, rightChild}) => {
return (
<header className='Header'>
<div className='header_left'>{leftChild}</div>
<div className='header_center'>{title}</div>
<div className='header_right'>{rightChild}</div>
</header>
)
}
export default Header;
Header.css
.Header {
display: flex;
align-items: center;
padding: 20px 0px;
border-bottom: 1px solid rgb(226, 226, 226);
}
.Header > div {
display: flex;
}
.Header .header_center {
width: 50%;
font-size: 25px;
justify-content: center;
}
.Header .header_left {
width: 25%;
justify-content: flex-start;
}
.Header .header_right {
width: 25%;
justify-content: flex-end;
}
App.js
import './App.css';
import Dairy 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 Header from './components/Header';
import Button from './components/Button';
function App() {
return (
<>
<Header
title={'Header'}
leftChild= {<Button text={'left'}/>}
rightChild={<Button text={'right'}/>}
/>
<Routes>
<Route path='/' element={ <Home/> }/>
<Route path='/new' element={ <New/> }/>
<Route path='/diary/:id' element={ <Dairy/> }/>
<Route path='*' element={ <Notfound/> }/>
</Routes>
</>
);
}
export default App;
현재 결과

데이터 만들기

App.js
import './App.css';
import Dairy 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 } from 'react';
import Header from './components/Header';
import Button from './components/Button';
const mockData = [
{
id: 1,
createdDate: new Date().getDate(),
emotionId: 1,
content:'1번 일기 내용'
},
{
id: 2,
createdDate: new Date().getDate(),
emotionId: 2,
content: '2번 일기 내용'
}
]
function reducer(state, action){
switch(action.type){
case 'CREATE':
return [action.data, ...state]
default:
return state;
}
}
function App() {
const [data, dispatch] = useReducer(reducer, mockData);
const idRef = useRef(3);
const onCreate = (createdDate, emotionId, content) => {
dispatch({
type: 'CREATE',
data: {
id: idRef.current++,
createdDate,
emotionId,
content
}
})
}
return (
<>
<Header
title={'Header'}
leftChild= {<Button text={'left'}/>}
rightChild={<Button text={'right'}/>}
/>
<button
onClick={() => {
onCreate(new Date().getTime(), 1, 'hello')
}}
>일기추가 테스트</button>
<Routes>
<Route path='/' element={ <Home/> }/>
<Route path='/new' element={ <New/> }/>
<Route path='/diary/:id' element={ <Dairy/> }/>
<Route path='*' element={ <Notfound/> }/>
</Routes>
</>
);
}
export default App;
현재 결과

수정하기
App.js
import './App.css';
import Dairy 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 } from 'react';
import Header from './components/Header';
import Button from './components/Button';
const mockData = [
{
id: 1,
createdDate: new Date().getDate(),
emotionId: 1,
content:'1번 일기 내용'
},
{
id: 2,
createdDate: new Date().getDate(),
emotionId: 2,
content: '2번 일기 내용'
}
]
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
)
default:
return state;
}
}
function App() {
const [data, dispatch] = useReducer(reducer, mockData);
const idRef = useRef(3);
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
}
})
}
return (
<>
<Header
title={'Header'}
leftChild= {<Button text={'left'}/>}
rightChild={<Button text={'right'}/>}
/>
<button
onClick={() => {
onCreate(new Date().getTime(), 1, 'hello')
}}
>일기추가 테스트</button>
<button
onClick={() => {
onUpdate(1, new Date().getTime(), 3, '수정된 일기 내용입니다.')
}}>
일기 수정 테스트
</button>
<Routes>
<Route path='/' element={ <Home/> }/>
<Route path='/new' element={ <New/> }/>
<Route path='/diary/:id' element={ <Dairy/> }/>
<Route path='*' element={ <Notfound/> }/>
</Routes>
</>
);
}
export default App;
현재 결과

삭제하기
App.js
import './App.css';
import Dairy 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 } from 'react';
import Header from './components/Header';
import Button from './components/Button';
const mockData = [
{
id: 1,
createdDate: new Date().getDate(),
emotionId: 1,
content:'1번 일기 내용'
},
{
id: 2,
createdDate: new Date().getDate(),
emotionId: 2,
content: '2번 일기 내용'
}
]
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;
}
}
function App() {
const [data, dispatch] = useReducer(reducer, mockData);
const idRef = useRef(3);
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 (
<>
<Header
title={'Header'}
leftChild= {<Button text={'left'}/>}
rightChild={<Button text={'right'}/>}
/>
<button
onClick={() => {
onCreate(new Date().getTime(), 1, 'hello')
}}
>일기추가 테스트</button>
<button
onClick={() => {
onUpdate(1, new Date().getTime(), 3, '수정된 일기 내용입니다.')
}}>
일기 수정 테스트
</button>
<button
onClick={() => {
onDelete(1);
}}
>
일기 삭제 테스트
</button>
<Routes>
<Route path='/' element={ <Home/> }/>
<Route path='/new' element={ <New/> }/>
<Route path='/diary/:id' element={ <Dairy/> }/>
<Route path='*' element={ <Notfound/> }/>
</Routes>
</>
);
}
export default App;
현재 결과

헤더 만들기
import './App.css';
import Dairy 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';
const mockData = [
{
id: 1,
createdDate: new Date().getDate(),
emotionId: 1,
content:'1번 일기 내용'
},
{
id: 2,
createdDate: new Date().getDate(),
emotionId: 2,
content: '2번 일기 내용'
}
]
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;
}
}
const DiaryStateContext = createContext();
const DiaryDispatchContext = createContext();
function App() {
const [data, dispatch] = useReducer(reducer, mockData);
const idRef = useRef(3);
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={ <Dairy/> }/>
<Route path='*' element={ <Notfound/> }/>
</Routes>
</DiaryDispatchContext.Provider>
</DiaryStateContext.Provider>
</>
);
}
export default App;
Home.js
import Button from "../components/Button";
import Header from "../components/Header";
import DiaryList from "../components/DiaryList";
const Home = () => {
return (
<div>
<Header
title={'2025년 9월'}
leftChile={ <Button text={'<'} /> }
rightChile={<Button text={'>'}/>}
/>
<DiaryList/>
</div>
)
};
export default Home;
몸통 만들기
DiaryList.js
import './DiaryList.css'
import DiaryItem from './DiaryItem'
import Button from './Button'
const DiaryList = () => {
return (
<div className='DiaryList'>
<div className='menu_bar'>
<select>
<option value={'latest'}>최신순</option>
<option value={'oldest'}>오래된순</option>
</select>
<Button text={'새 일기 쓰기'} type={'POSITIVE'}/>
</div>
<div className='list_warapper'>
<DiaryItem/>
</div>
</div>
)
}
export default DiaryList;
DiaryList.css
.DiaryList .menu_bar {
margin: 20px 0px;
display: flex;
gap: 10px;
}
.DiaryList .menu_bar select {
background-color: rgb(236, 236, 236);
border: none;
border-radius: 5px;
padding: 10px 20px;
font-size: 18px;
cursor: pointer;
}
.DiaryList .menu_bar button {
flex: 1;
}
DiaryItem.js
import './DiaryItem.css'
import { getEmotionImage } from '../util/get-emotion-image';
import Button from './Button';
const DiaryItem = () => {
const emotionId = 1;
return (
<div className='DiaryItem'>
<div className={`img_section img_section_${emotionId}`}>
<img src={getEmotionImage(emotionId)}/>
</div>
<div className='imfo_section'>
<div className='created_date'>
{ new Date().toLocaleDateString()}
</div>
<div className='content'>
일기 컨텐츠
</div>
</div>
<div className='button_section'>
<Button text={'수정하기'}/>
</div>
</div>
)
};
export default DiaryItem;
DiaryItem.css
.DiaryItem {
display: flex;
gap: 15px;
justify-content: space-between;
padding: 15px 0px;
border-bottom: 1px solid rgb(236, 236, 236);
}
.DiaryItem .img_section {
min-width: 120px;
height: 80px;
display: flex;
justify-content: center;
cursor: pointer;
border-radius: 5px;
}
.DiaryItem .img_section > img {
width: 50%;
}
.DiaryItem .img_section_1 {
background-color: rgb(100, 201, 100);
}
.DiaryItem .img_section_2 {
background-color: rgb(157, 215, 114);
}
.DiaryItem .img_section_3 {
background-color: rgb(253, 206, 33);
}
.DiaryItem .img_section_4 {
background-color: rgb(253, 132, 70);
}
.DiaryItem .img_section_5 {
background-color: rgb(253, 86, 95);
}
.DiaryItem .info_section {
flex: 1;
cursor: pointer;
}
.DiaryItem .info_section .created_date {
font-weight: bold;
font-size: 25px;
}
.DiaryItem .info_section .content {
font-size: 18px;
}
.DiaryItem .button_section {
min-width: 70px;
}
현재 결과

'Front > React' 카테고리의 다른 글
| Day11_react(6)_Pm (0) | 2025.09.09 |
|---|---|
| Day11_react(6)_Am (0) | 2025.09.09 |
| Day10_react(5)_Am (0) | 2025.09.08 |
| Day9_react(4)_Pm (0) | 2025.09.05 |
| Day9_react(4)_Am (0) | 2025.09.05 |