지난 게시물에서 게시글을 만들기 위한 기본 페이지 구조를 작성했었다.
이번에는 게시글의 작성과 수정, 삭제 그리고 게시글 보기 (CRUD)를 만들어보고자 한다.
1. 글 생성
<app.js>
//page-create_post
function Create(props){
return (
<article>
<form onSubmit={event=>{
event.preventDefault();
const title = event.target.title.value;
const body = event.target.body.value;
props.onCreate(title, body);
}}>
<div class="info_create">
<dl>
<dt>제목</dt>
<dd><input class="c_title" type="text" name="title" placeholder="title" /></dd>
</dl>
</div>
<div class="body_create">
<p><textarea class="c_body" name='body' placeholder='body'></textarea></p>
</div>
<div class="button">
<input type='submit' value='create'></input>
</div>
</form>
</article>
)
}
글 생성을 위한 템플릿이다. 작성자는 로그인을 하도록 하여 자동으로 작성되게 하기 위해 비워두었고, 날짜는 자동으로 등록되도록 하기 위해 비워두었다.
form태그를 이용하여 submit 버튼이 눌렸을때 작성된 title값과 body값을 저장하여 이를 글 생성 함수를 호출한 쪽으로 전달해준다.
if(mode === 'HOME'){...}
...
else if(mode === 'CREATE'){
content = <Create onCreate={(title, body)=>{
const list = { title: title, body: body, writer: member};
const newplist = [...plist];
newplist.push(list);
setPlist(newplist);
setMode('POST');
let now;
for(let i=0; i<plist.length; i++){
if(title === plist[i].title){
now = plist[i].id;
}
}
setPostid(now);
}}></Create>
}
전달받은 값을 토대로 형식에 맞게 따로 저장한 뒤, 기존 데이터의 복사본에 push문을 통해 추가해준다.
완성된 새로운 데이터를 set문으로 마무리한다.
2. 글 조회
글 조회는 이미 글 목록을 만들면서 추가해두었는데
if(postid != null){
let title, body, writer, date = null;
for(let i=0; i<plist.length; i++){
if(plist[i].id === postid){
title = plist[i].title;
body = plist[i].body;
writer = plist[i].writer;
date = plist[i].date;
}
}
content = <Postin postid={postid} title={title} body={body} writer={writer} date={date}
setMode={setMode} member={member} plist={plist} setPlist={setPlist} setPostid={setPostid}></Postin>
}
이 부분이 바로 그것이다.
if문 안의 조건은 게시글 클릭시 해당 게시글의 id값을 postid로 저장하게 되는데 이 값이 null값이 아닐때 실행되도록 한 것이다.
//page-view_post
function Postin(props){
return(
<article>
<div class="post_view">
<div class="info_view">
<p class="info_title">{props.title}</p>
<p class="info_writer">{props.writer}</p>
<p class="info_date">{props.date}</p>
</div>
<div class="body_view">
{props.body}
</div>
<div class="button">
<a href="/post/update" onClick={event=>{
event.preventDefault();
props.setMode('UPDATE');
}}>수정</a>
<a href="/post" onClick={event=>{
event.preventDefault();
const dlist;
for(let i=0; i<props.plist.length; i++){
if(props.postid !== props.plist[i].id){
dlist.push(props.plist[i]);
}
}
props.setPlist(dlist);
props.setMode('POST');
props.setPostid(null);
}}>삭제</a>
<div class="list_bt">
<a href="/post" onClick={event => {
event.preventDefault();
props.setPostid(null);
}}>목록</a>
</div>
</div>
</div>
</article>
)
}
전달받은 데이터를 단순히 보여주면 되기에 이렇게 코드를 작성하였다.
동시에 수정과 삭제 역시 이 페이지로부터 시작되기 때문에 추가로 수정 버튼과 삭제 버튼을 만들어주고 mode값만 변경하도록 하였다.
3. 글 수정
수정 버튼을 누르면 mode='UPDATE'로 적용이 되기 때문에 이 조건에 맞게 코드를 추가하였다.
if(mode === 'HOME'){...}
...
else if(mode === 'UPDATE'){
let title, date, body = null;
for(let i=0; i<plist.length; i++){
if(plist[i].id === postid){
title = plist[i].title;
date = plist[i].date;
body = plist[i].body;
}
}
content = <Update title={title} body={body}
onUpdate={(title, body)=>{
const ulist = {title: title, body: body, writer: member, date: date, id: postid};
const newuplist = [...plist];
for(let i=0; i<plist.length; i++){
if(newuplist[i].id === postid){
newuplist[i] = ulist;
}
}
setPlist(newplist);
setMode('POST');
setPostid(postid);
}}></Update>
}
//page-update_mypost
function Update(props){
const [title, setTitle] = useState(props.title);
const [body, setBody] = useState(props.body);
return (
<article>
<form onSubmit={event=>{
event.preventDefault();
props.onUpdate(title, body);
}}>
<div class="info_create">
<dl>
<dt>제목</dt>
<dd><input class="c_title" type="text" name="title" value={title}
placeholder="title" onChange={event=>{setTitle(event.target.value);}}/></dd>
</dl>
</div>
<div class="body_create">
<p><textarea class="c_body" name='body' value={body}
placeholder='body'onChange={event=>{setBody(event.target.value);}}></textarea></p>
</div>
<div class="button">
<input type='submit' value='수정'></input>
</div>
</form>
</article>
)
}
기존 글의 내용을 보여주어야 하기 때문에 value를 통해 값을 보여주도록 하였다.
하지만 이렇게 하면 내용의 수정이 불가하기 때문에 따로 title과 body의 useState문을 만들고 onChange를 통해 값의 변화가 생길때마다 저장할 수 있도록 하여 수정을 가능하게 하였다.
4. 글 삭제
글 삭제는 별다른 페이지가 필요하지 않기 때문에 삭제 버튼을 누름과 동시에 처리되도록 하였다.
//page-view_post
function Postin(props){
return(
<article>
<div class="post_view">
<div class="info_view">
<p class="info_title">{props.title}</p>
<p class="info_writer">{props.writer}</p>
<p class="info_date">{props.date}</p>
</div>
<div class="body_view">
{props.body}
</div>
<div class="button">
<a href="/post/update" onClick={event=>{
event.preventDefault();
props.setMode('UPDATE');
}}>수정</a>
<a href="/post" onClick={event=>{
event.preventDefault();
const dlist;
for(let i=0; i<props.plist.length; i++){
if(props.postid !== props.plist[i].id){
dlist.push(props.plist[i]);
}
}
props.setPlist(dlist);
props.setMode('POST');
props.setPostid(null);
}}>삭제</a>
<div class="list_bt">
<a href="/post" onClick={event => {
event.preventDefault();
props.setPostid(null);
}}>목록</a>
</div>
</div>
</div>
</article>
)
}
글 번호가 같지 않은 글들만 저장하는 방식이다.