노트

[React] 리액트 연습 - 페이징이 가능한 방명록 만들기1 본문

코딩/웹 프론트

[React] 리액트 연습 - 페이징이 가능한 방명록 만들기1

_Myway 2020. 7. 14. 17:13

.

리액트 강의를 간단하게 듣고 연습으로 페이징이 가능한 방명록을 만들어봤습니다.

css는 따로 사용하지 않았습니다.

1. 입력 항목 : 제목, 내용, 작성자, 작성비밀번호 
2. 출력 항목 : 제목, 내용, 작성자, 작성일시
3. 항목 삭제를 하기 위해서는 작성비밀번호를 입력해야함
4. 한 페이지에 10개씩 항목이 출력되며, 페이징 처리가 되어야 함
5. 입출력 데이터는 array형태로 state 에 저장 (Database 사용x)

 

저는 Visual Code를 사용했고, npm으로 create-react-app을 설치해줬다고 가정합니다.(yarn으로 설치도 가능)

먼저 개발을 진행할 폴더를 만들어줍니다.

create-react-app 만들-폴더-이름
cd 만든폴더
npm start //또는 yarn start

를 하면 기본 리액트 페이지가 나오게 됩니다.

편집기에서 해당 프로젝트를 연 후 src의 App.js를 열면

import React, {Component} from 'react';

class App extends Component {  
  render(){
    return (
    <div className="App">
    </div>
    );
  }
}

export default App;

 

대충 위와 같은 코드가 나오게 됩니다. div태그 안에 뭐라고 쏼라쏼라 적혀있는데 일단 그걸 싹 지워줍니다.

그리고 위쪽에 import된 css파일들도 싹 지워줍니다.

그리고 ctrl+s를 눌러주면 화면이 새로고침 되면서 아무것도 없는 백지가 나옵니다. 

이제 시작하면 되겠네요.

.

.

.

 

 

 

일단 저는 '방명록' 이라는 글자를 크게 적고 그 아래에 토글버튼 형식으로 읽기와 쓰기를 전환하는 형태의 방명록을 만들고 싶습니다. 그래서 커다랗게 방명록과 버튼을 하나 만들어줍니다.

import React, {Component} from 'react';

class App extends Component {  
  render(){
    return (
    <div className="App">
    	<h1>방명록</h1>
        <p>
          <button>작성하기</button>
        </p>
    </div>
    );
  }
}

export default App;

이러면 대충 이렇게 나타나게 됩니다.

그 다음으로 읽기와 쓰기모드로 나누어 '작성하기' 버튼을 누르면 글을 쓸 수 있게 화면을 전환시키기 위해 state에 mode를 추가해줍니다. 기본값은 read로 둡니다. 그 다음 버튼에 토글 기능을 추가해줍니다. onClick함수를 이용하여 클릭 시 토글로 read와 write가 바뀌게 해줍니다. 리렌더링 방지를 위해 e.preventDefault()를 해주는 것도 잊지 맙시다. 마지막에 bind(this)를 해주는 이유는 함수 안에서는 this를 사용할 수 없기 때문입니다.

state 안의 contents는 방명록을 등록했을 때 저장되는 곳입니다. 샘플데이터를 하나만 넣어줍니다.

이제 프로젝트 폴더에 components 폴더를 하나 추가해줍니다. 그 다음 ReadGuest.js와 WriteGuest.js를 만들어줍니다. 각각 읽기모드, 쓰기모드입니다. 초기 틀은 맨 위의 App.js와 똑같이 하면 됩니다. 그리고 App.js 맨 위에서 import해옵니다.

저는 버튼 밑에 토글로 번갈아가며 모드가 바뀌게 하고 싶기 때문에 버튼 밑에 작성할 코드를 따로 함수로 빼서 사용할 것입니다. ModeHandler()라는 함수를 하나 만들어줍니다. 안에서 if문으로 모드가 바뀔 때 보여줄 컴포넌트를 선택합니다.

import React, {Component} from 'react';
import ReadGuest from "./components/ReadGuest"
import WriteGuest from "./components/WriteGuest"

class App extends Component {  
  constructor(props){
    super(props);
    this.state = {
      mode:'read',
      contents : [
      	{ title:'공지사항', content:'공지입니다.', id:'관리자', write_date:'2020. 7. 8. 오전 9:49:23', pw:'1' },
      ]
    }
    modeHandler(){
      var nowMode = null;
      if(this.state.mode === 'read'){
        nowMode=<ReadGuest></ReadGuest>
      }else{
        nowMode=<WriteGuest></WriteGuest>
      }
      return nowMode
    }
  render(){
    return (
    <div className="App">
    	<h1>방명록</h1>
        <p>
          <button onClick={function(e){
                  e.preventDefault();
                  if(this.state.mode==='read'){
                    this.setState({
                      mode : "write"
                    });
                  }else{
                    this.setState({
                      mode : "read"
                    });
                  }
                }.bind(this)}>{this.state.mode==='read'?'작성하기':'뒤로가기'}</button>
        </p>
        {this.modeHandler()}
    </div>
    );
  }
}

export default App;

 

크롬 확장 프로그램 중에 react developer tools 라는게 있는데 이걸 사용하면 리액트 컴포넌트별로 state, props 등을 자세히 보여줍니다. Component 탭에서 왼쪽에 App을 누르면 오른쪽에서 App의 props와 state를 볼 수 있는데 state의 mode에 read라고 되어 있고, App 아래에 ReadGuest라고 나와 있습니다. 작성하기 버튼을 계속 누르면 뒤로가기와 작성하기가 번갈아 표시되고 read와 write가 바뀌면서 ReadGuest와 WriteGuest가 바뀝니다.

 

 

 

.

.

.

기본값은 read로 해놨지만 write부터 먼저 해봅시다. App.js에서 mode를 write로 바꿔놓으면 테스팅하기 편합니다.

WrietGuest.js

좀 보기 힘들 수 있는데 먼저 아래의 <p>태그 안의 내용을 보면 그냥 방명록을 위한 form입니다. 그래서 그 밖에 <form>태그로 감싸줬습니다. 대충 이렇게 화면구성을 했고요.

중요한건 form태그 안의 onSubmit부분인데 사용자가 작성한 데이터를 App.js에 넘겨주는 역할입니다. 등록 버튼을 눌렀을 때 동작합니다. 버튼을 누를 때마다 렌더링되지 않게하기위해 e.preventDefault()를 해줬습니다. 먼저 날짜를 저장하기위해 new Date()를 이용했고, 변수를 하나 선언해 form에 적힌 내용을 저장해줍니다. 저장해준 후 아래서 validation체크도 해줍니다. 

import React, {Component} from 'react';

class WriteGuest extends Component {
    render(){
        return(
            <div>
                <form onSubmit={function(e){
                    e.preventDefault();
                    var date = new Date();
                    var ymdhms = date.toLocaleString();
                    var g_data = {
                        title:e.target.title.value,
                        content:e.target.content.value,
                        id:e.target.id.value,
                        write_date:ymdhms,
                        pw:e.target.pw.value,
                    }
                    if(g_data.title===""){
                        alert('제목을 입력해주세요!')
                    }else if(g_data.content===""){
                        alert('내용을 입력해주세요!')
                    }else if(g_data.pw===""){
                        alert('비밀번호를 입력해주세요!')
                    }
                    else{
                        if(g_data.id===""){
                            // alert('닉네임을 입력해주세요!')
                            g_data.id='익명의 방문자'
                        }
                        this.props.onSubmit(g_data);
                        alert('등록되었습니다.');
                    }
                }.bind(this)}>
                    <p>
                        제목 : <input type="text" name="title" placeholder="제목"></input>
                        닉네임 : <input type="text" name="id" placeholder="닉네임"></input>
                    </p>
                    <p>비밀번호 : <input type="password" name="pw" placeholder="비밀번호"></input></p>
                    <p><textarea style={{width:'450px',height:'150px'}}
                    name="content" placeholder="내용을 입력하세요"></textarea></p>
                    <p>
                        <input type="submit" value="등록"></input>
                    </p>
                </form>
            </div>
        );
    }
}

export default WriteGuest;

WriteGuest 끝

 

 

 

이제 다시 App.js로 가서 넘겨준 데이터를 받아옵시다. modeHandler()의 WriteGuest 컴포넌트를 수정합니다.

WriteGuest에서 넘겨주는 g_data변수를 인자로 갖는 함수입니다. state의 불변성을 지키면서 원래 있던 기본데이터와 합쳐주기위해 새로운 변수를 만들어서 합쳐줍니다. 방명록이기 때문에 최신데이터가 맨 앞에 오도록 합쳐준 후 setState로 contents를 새로 선언한 변수로 바꿉니다. 등록 버튼을 눌렀으므로 write모드에서 read모드로 바뀌어야 하므로 mode를 read로 바꿔줍니다.

modeHandler(){
    var nowMode = null;
    if(this.state.mode === 'read'){
      nowMode=<ReadGuest></ReadGuest>
    }else{
      nowMode=<WriteGuest onSubmit={function(g_data){
                  var _contents = [{ 
                      title:g_data.title,
                      content:g_data.content,
                      id:g_data.id,
                      write_date:g_data.write_date,
                      pw:g_data.pw,
                      num:this.now_num
                    }, ...this.state.contents]
                  this.setState({
                    mode:'read',
                    contents:_contents,
                  })
                }.bind(this)}></WriteGuest>
    }
    return nowMode
  }

.

.

.

추가된 데이터를 확장 프로그램으로 볼 수 있습니다. (캡처본은 다 짜놓고 올리는거라 데이터가 좀 많아요)

읽기모드와 num에 대한 설명은 다음편에,,

쨘 이러면 등록 끝

.

.

.

참고한 강의 : 생활코딩, 벨로퍼트

Comments