40 Edit 페이지 route 추가
routes.js
{
path: '/blogs/:id/edit',
component: EditPage
},
로 수정. 무엇을 edit하는 것인지 알 수 있게
ShowPage.js
import { useParams } from "react-router";
import axios from 'axios';
import { useEffect, useState } from "react";
import LoadingSpinner from "../components/LoadingSpinner";
import { Link } from "react-router-dom"; //추가
const ShowPage = () => {
const { id } = useParams();
const [post, setPost] = useState(null);
const [loading, setLoading] = useState(true);
const getPost = (id) => {
axios.get(`http://localhost:3001/posts/${id}`).then((res) => {
setPost(res.data);
setLoading(false);
})
};
useEffect(() => {
getPost(id);
}, [id]);
const printDate = (timestamp) => {
return new Date(timestamp).toLocaleString();
}
if (loading) {
return <LoadingSpinner />
}
return (
<div>
<div className="d-flex"> {/*추가*/}
<h1 className="flex-grow-1">{post.title}</h1>
<div>
<Link
className="btn btn-primary"
to={`/blogs/${id}/edit`}
>
Edit
</Link>
</div>
</div>
<small className="text-muted">
Created At: {printDate(post.createdAt)}
</small>
<hr />
<p>{post.body}</p>
</div>
);
}
export default ShowPage;
41 수정 페이지 폼 1
Create할 때 썼던 BlogForm 재사용
EditPage.js
import BlogForm from "../components/BlogForm";
const EditPage = () => {
return (
<div>
<BlogForm editing={true} />
</div>
);
};
export default EditPage;
BlogForm.js
import { useEffect, useState } from 'react';
import axios from 'axios';
import { useHistory } from 'react-router';
import { useParams } from 'react-router-dom/cjs/react-router-dom.min';
const BlogForm = ({ editing }) => { //editing일 경우에는
const history = useHistory();
const { id } = useParams(); //추가
const [title, setTitle] = useState('');
const [body, setBody] = useState('');
useEffect(() => { //추가
axios.get(`http://localhost:3001/posts/${id}`).then(res => {
setTitle(res.data.title);
setBody(res.data.body);
})
}, [id]);
const onSubmit = () => {
axios.post('http://localhost:3001/posts', {
title: title,
body: body,
createdAt: Date.now()
}).then(() => {
history.push('/blogs');
})
};
return (
<div>
<h1>{editing ? 'Edit' : 'Create'} a blog post</h1> {/*변경*/}
<div className="mb-3">
<label className="form-label">Title</label>
<input
className="form-control"
value={title}
onChange={ (e) => {
setTitle(e.target.value);
} }
/>
</div>
<div className="mb-3">
<label class Name="form-label">Body</label>
<textarea
className="form-control"
value={body}
onChange={ (e) => {
setBody(e.target.value);
} }
rows="10" //추가
/>
</div>
<button
className="btn btn-primary"
onClick={onSubmit}
>
{editing ? 'Edit' : 'Post'} {/*변경*/}
</button>
</div>
);
};
BlogForm.propTypes = { //edit
editing: Boolean
}
BlogForm.defaultProps = { //create
editing: false
}
export default BlogForm;
42 수정 페이지 폼 2
button을 누르면 onSubmit함수 공유해서 실행해서 db에 post 생성..
-> 이 안에서도 condition을 넣어서 editing일 경우에는 ~
const onSubmit = () => {
if (editing) {
axios.patch(`http://localhost:3001/posts/${id}`, {
title: title,
body: body,
}).then(res => { //response가 오면
console.log(res);
})
} else {
axios.post('http://localhost:3001/posts', {
title: title,
body: body,
createdAt: Date.now()
}).then(() => {
history.push('/blogs');
})
}
};
-> 수정이 잘 된다!
43 수정 페이지 폼 3
title이랑 body 안 바꾸면 버튼 비활성화
Edit 완료하면 이전 페이지로 이동
BlogForm.js
import { useEffect, useState } from 'react';
import axios from 'axios';
import { useHistory } from 'react-router';
import { useParams } from 'react-router-dom/cjs/react-router-dom.min';
const BlogForm = ({ editing }) => {
const history = useHistory();
const { id } = useParams();
const [title, setTitle] = useState('');
const [originalTitle, setOriginalTitle] = useState(''); //추가
const [body, setBody] = useState('');
const [originalBody, setOriginalBody] = useState(''); //추가
useEffect(() => {
if (editing) { //빼먹은거
axios.get(`http://localhost:3001/posts/${id}`).then(res => {
setTitle(res.data.title);
setOriginalTitle(res.data.title);
setBody(res.data.body);
setOriginalBody(res.data.body);
})
}
}, [id, editing]);
const isEdited = () => {
return title !== originalTitle || body !== originalBody; //수정이 된 거
}
const onSubmit = () => {
if (editing) {
axios.patch(`http://localhost:3001/posts/${id}`, {
title: title,
body: body,
}).then(res => {
console.log(res);
history.push(`/blogs/${id}`) //추가
})
} else {
axios.post('http://localhost:3001/posts', {
title: title,
body: body,
createdAt: Date.now()
}).then(() => {
history.push('/blogs');
})
}
};
return (
<div>
<h1>{editing ? 'Edit' : 'Create'} a blog post</h1>
<div className="mb-3">
<label className="form-label">Title</label>
<input
className="form-control"
value={title}
onChange={ (e) => {
setTitle(e.target.value);
} }
/>
</div>
<div className="mb-3">
<label class Name="form-label">Body</label>
<textarea
className="form-control"
value={body}
onChange={ (e) => {
setBody(e.target.value);
} }
rows="10"
/>
</div>
<button
className="btn btn-primary"
onClick={onSubmit}
disabled={editing && !isEdited()} //추가
>
{editing ? 'Edit' : 'Post'}
</button>
</div>
);
};
BlogForm.propTypes = {
editing: Boolean
}
BlogForm.defaultProps = {
editing: false
}
export default BlogForm;
=> originalTitle.........질문 ★
44 수정 페이지 폼 4
edit 버튼 옆 cancel 버튼
BlogForm.js
import { useEffect, useState } from 'react';
import axios from 'axios';
import { useHistory } from 'react-router';
import { useParams } from 'react-router-dom/cjs/react-router-dom.min';
const BlogForm = ({ editing }) => {
const history = useHistory();
const { id } = useParams();
const [title, setTitle] = useState('');
const [originalTitle, setOriginalTitle] = useState('');
const [body, setBody] = useState('');
const [originalBody, setOriginalBody] = useState('');
useEffect(() => {
if (editing) {
axios.get(`http://localhost:3001/posts/${id}`).then(res => {
setTitle(res.data.title);
setOriginalTitle(res.data.title);
setBody(res.data.body);
setOriginalBody(res.data.body);
})
}
}, [id, editing]);
const isEdited = () => {
return title !== originalTitle || body !== originalBody;
};
const goBack = () => { //추가
if (editing) {
history.push(`/blogs/${id}`);
} else { //create인 경우 -> 그냥 리스트로 이동
history.push('/blogs');
}
};
const onSubmit = () => {
if (editing) {
axios.patch(`http://localhost:3001/posts/${id}`, {
title: title,
body: body,
}).then(res => {
console.log(res);
history.push(`/blogs/${id}`)
})
} else {
axios.post('http://localhost:3001/posts', {
title: title,
body: body,
createdAt: Date.now()
}).then(() => {
history.push('/blogs');
})
}
};
return (
<div>
<h1>{editing ? 'Edit' : 'Create'} a blog post</h1>
<div className="mb-3">
<label className="form-label">Title</label>
<input
className="form-control"
value={title}
onChange={ (e) => {
setTitle(e.target.value);
} }
/>
</div>
<div className="mb-3">
<label class Name="form-label">Body</label>
<textarea
className="form-control"
value={body}
onChange={ (e) => {
setBody(e.target.value);
} }
rows="10"
/>
</div>
<button
className="btn btn-primary"
onClick={onSubmit}
disabled={editing && !isEdited()}
>
{editing ? 'Edit' : 'Post'}
</button>
<button //추가
className="btn btn-danger ms-2"
onClick={goBack}
>
Cancel
</button>
</div>
);
};
BlogForm.propTypes = {
editing: Boolean
}
BlogForm.defaultProps = {
editing: false
}
export default BlogForm;
45 수정 페이지 폼 5
공개여부 체크박스
BlogForm.js
import { useEffect, useState } from 'react';
import axios from 'axios';
import { useHistory } from 'react-router';
import { useParams } from 'react-router-dom/cjs/react-router-dom.min';
const BlogForm = ({ editing }) => {
const history = useHistory();
const { id } = useParams();
const [title, setTitle] = useState('');
const [originalTitle, setOriginalTitle] = useState('');
const [body, setBody] = useState('');
const [originalBody, setOriginalBody] = useState('');
const [publish, setPublish] = useState(false); //추가
const [originalPublish, setOriginalPublish] = useState(false); //추가
useEffect(() => {
if (editing) {
axios.get(`http://localhost:3001/posts/${id}`).then(res => {
setTitle(res.data.title);
setOriginalTitle(res.data.title);
setBody(res.data.body);
setOriginalBody(res.data.body);
setPublish(res.data.publish);
setOriginalPublish(res.data.publish);
})
}
}, [id, editing]);
const isEdited = () => {
return title !== originalTitle
|| body !== originalBody
|| publish !== originalPublish; //축
};
const goBack = () => {
if (editing) {
history.push(`/blogs/${id}`);
} else {
history.push('/blogs');
}
};
const onSubmit = () => {
if (editing) {
axios.patch(`http://localhost:3001/posts/${id}`, {
title: title,
body: body,
publish: publish
}).then(res => {
console.log(res);
history.push(`/blogs/${id}`)
})
} else {
axios.post('http://localhost:3001/posts', {
title: title,
body: body,
publish: publish,
createdAt: Date.now()
}).then(() => {
history.push('/blogs');
})
}
};
const onChangePublish = (e) => { //추가
console.log(e.target.checked);
setPublish(e.target.checked);
};
return (
<div>
<h1>{editing ? 'Edit' : 'Create'} a blog post</h1>
<div className="mb-3">
<label className="form-label">Title</label>
<input
className="form-control"
value={title}
onChange={ (e) => {
setTitle(e.target.value);
} }
/>
</div>
<div className="mb-3">
<label class Name="form-label">Body</label>
<textarea
className="form-control"
value={body}
onChange={ (e) => {
setBody(e.target.value);
} }
rows="10"
/>
</div>
<div className="form-check mb-3"> {/*추가*/}
<input
className="form-check-input"
type="checkbox"
checked = {publish}
onChange={onChangePublish}
/>
<label className="form-check-label">
Publish
</label>
</div>
<button
className="btn btn-primary"
onClick={onSubmit}
disabled={editing && !isEdited()}
>
{editing ? 'Edit' : 'Post'}
</button>
<button
className="btn btn-danger ms-2"
onClick={goBack}
>
Cancel
</button>
</div>
);
};
BlogForm.propTypes = {
editing: Boolean
}
BlogForm.defaultProps = {
editing: false
}
export default BlogForm;
'Frontend > 프로젝트로 배우는 React.js' 카테고리의 다른 글
섹션 7. 블로그 리스트 페이지 수정 (2) | 2023.12.05 |
---|---|
섹션 5. 블로그 디테일 페이지 (1) | 2023.11.29 |
Axios Error: Network Error (0) | 2023.11.29 |
섹션 4. 블로그 리스트 (1) | 2023.11.26 |
섹션 3. React Router로 페이지 추가하기 (0) | 2023.11.06 |