본문 바로가기

카테고리 없음

간단한 게시판 만들기 - 2

지난 게시물에서 게시글을 만들기 위한 기본 페이지 구조를 작성했었다.

이번에는 게시글의 작성과 수정, 삭제 그리고 게시글 보기 (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>
  )
}

글 번호가 같지 않은 글들만 저장하는 방식이다.