본문 바로가기
프로그래밍 개발/ReactJs

ReactJs - Create 기능 구현

by Jinseok Kim 2021. 1. 4.
반응형

 Create 기능 구현

 

 

 

 

 

 

 

1. mode 전환 기능

 

 

 

App.js

import React, { Component } from 'react';
import TOC from "./components/TOC";
import ReadContent from "./components/ReadContent" //추가
import Subject from "./components/Subject"
import Control from "./components/Control"
import CreateContent from "./components/CreateContent"//추가
import './App.css';
class App extends Component {
  constructor(props){
    super(props);
    this.state = {
      mode:'TEST1',
      
      selected_content_id:2,
      subject:{title:'WEB event TEST', sub:'this is test start'},
      TEST1:{title:'TEST1', desc:'this is test1'},
      contents:[
        {id:1, title:'TEST2-1', desc:'HTML is for information'},
        {id:2, title:'TEST2-2', desc:'CSS is for design'},
        {id:3, title:'TEST2-3', desc:'JavaScript is for interactive'}
      ]
    }
  }
  render() {
    console.log('App render');
    var _title, _desc, _article = null; //_article 변수 추가
    if(this.state.mode ===  'TEST1'){
      _title = this.state.TEST1.title;
      _desc = this.state.TEST1.desc;
      _article = <ReadContent title={_title} desc={_desc}></ReadContent>//content 영역 변수화    
    } else if(this.state.mode === 'TEST2'){
      var i = 0;
      while(i < this.state.contents.length){
        var data = this.state.contents[i];
        if(data.id === this.state.selected_content_id) {
          _title = data.title;
          _desc = data.desc;
          break;
        }
        i = i + 1;
      }
        _article = <ReadContent title={_title} desc={_desc}></ReadContent>//content 영역 변수화
    }else if(this.state.mode === 'create'){// create 버튼 이벤트 발동시 함수 동작
        _article = <CreateContent></CreateContent>//content 영역 Read와 create로 분리 후 변수화
    }
    return (
      <div className="App">
        <Subject 
          title={this.state.subject.title} 
          sub={this.state.subject.sub}
          onChangePage={function(){
            this.setState({mode:'TEST1'});
          }.bind(this)}
        >
        </Subject>
        <TOC 
         
          onChangePage={function(id){
            this.setState({
              mode:'TEST2',
              selected_content_id:Number(id)
            });
          }.bind(this)} 
          data={this.state.contents}
        ></TOC>
            //control.js의  props 추가. create, update, delete 기능을 구현하기 위함임
            //onChangeMode의 인자의 매개변수 _mode가 create, update, delete을 받아내어
            //실제로 setState 메소드를 이용하여 state의 mode 값을 받은 매개변수 값으로 변동시킨다.
              <Control onChangeMode={function(_mode){
                  this.setState({
                      mode:_mode
                  });
                  
              }.bind(this)}></Control>
        {_article} //content 영역 변수화
      </div>
    );
  }
}
export default App;

 

 

 

control.js

import React, { Component } from 'react';
class Control extends Component {
    render(){
      console.log('Subject render');
      return (
      // <li>마다 create, update, delete 각각의 링크를 걸어주어 클릭 이벤트 발생시 각각 
      // onChangeMode() 메소드 인자로 create, update, delete을 props로 App.js에 보내준다.
         <ul>
                  <li><a href='/create' onClick={function(e){
                        e.preventDefault();
                        this.props.onChangeMode('create')
                    }.bind(this)}>create</a></li>
                        
                  <li><a href='/update' onClick={function(e){
                        e.preventDefault();
                       this.props.onChangeMode('update')   
                    }.bind(this)}>update</a></li>
                        
                  <li><input onClick={function(e){
                        e.preventDefault();
                       this.props.onChangeMode('delete')
                        
                    }.bind(this)}type='button' value='delete'></input></li>
                    
              </ul>
      );
    }
  }
export default Control;

 

 

 

 

CreateContent.js

import React, {Component} from 'react';


class CreateContent extends Component{
  render(){
    return (
    //create 버튼을 누르면 props로 아래 article 태그 정보들이 보내진다.
      <article>
          <h2>Create</h2>
          <form>
        </form>
      </article>
    );
  }
}
export default CreateContent;

 

 

 

 

ReadCreate.js

import React, {Component} from 'react';


class ReadContent extends Component{
  render(){
    return (
      <article>
          <h2>{this.props.title}</h2>
          {this.props.desc}
      </article>
    );
  }
}
export default ReadContent;

create 링크를 누르자 정상적으로 mode가 변환되어 작동하는 것을 확인 할 수 있다.

 

 

 

 

 

 

2. form 기능 구현과 onSubmit 구현

 

 

 

CreateContent.js

import React, {Component} from 'react';


class CreateContent extends Component{
  render(){
    return (
      <article>
          <h2>Create</h2>
          //아래와 같이 form의 기능들을 추가하였다.
        <form action="/create_process" method="post" 
           onSubmit={function(e){
          e.preventDefault();
        alert('test');
        //onSubmit 메소드의 인자로 submit 버튼을 눌러 발생되는 이벤트 당시 추출되는 값들을
        //porps으로 보내었다.
        this.props.onSubmit(
        e.target.title.value,
        e.target.desc.value    
        );
          }.bind(this)}
    >
        <p><input type="text" name="title" placeholder="title"></input>        
        </p>
        <p><textarea name="desc"  placeholder="description"></textarea>  
        </p>
        <p><input type="submit"></input>  
        </p>
        
        </form>
      </article>
    );
  }
}
export default CreateContent;

 

 

 

App.js

.
.
.
.
else if(this.state.mode === 'create'){
        _article = <CreateContent onSubmit={function(_title,_desc){
            console.log(_title, _desc);
        }.bind(this)}></CreateContent>
    }
    //props으로 보낸 값을 받아 onSubmit 메소드를 이용하여 전달받았다.

정상적으로 form의 기능과 onSubmit 기능이 실행되는 것을 확인 할 수 있었다.

 

 

 

 

 

3. contents 변경

 

 

App.js

import React, { Component } from 'react';
import TOC from "./components/TOC";
import ReadContent from "./components/ReadContent"
import Subject from "./components/Subject"
import Control from "./components/Control"
import CreateContent from "./components/CreateContent"
import './App.css';
class App extends Component {
  constructor(props){
    super(props);
    this.max_content_id = 3;  //추가. id값을 사용할 목적
    this.state = {
      mode:'create',
      
      selected_content_id:2,
      subject:{title:'WEB event TEST', sub:'this is test start'},
      TEST1:{title:'TEST1', desc:'this is test1'},
      contents:[
        {id:1, title:'TEST2-1', desc:'HTML is for information'},
        {id:2, title:'TEST2-2', desc:'CSS is for design'},
        {id:3, title:'TEST2-3', desc:'JavaScript is for interactive'}
      ]
    }
  }
  render() {
    console.log('App render');
    var _title, _desc, _article = null;
    if(this.state.mode ===  'TEST1'){
      _title = this.state.TEST1.title;
      _desc = this.state.TEST1.desc;
      _article = <ReadContent title={_title} desc={_desc}></ReadContent>    
    } else if(this.state.mode === 'TEST2'){
      var i = 0;
      while(i < this.state.contents.length){
        var data = this.state.contents[i];
        if(data.id === this.state.selected_content_id) {
          _title = data.title;
          _desc = data.desc;
          break;
        }
        i = i + 1;
      }
        _article = <ReadContent title={_title} desc={_desc}></ReadContent>
    }else if(this.state.mode === 'create'){
        _article = <CreateContent onSubmit={function(_title,_desc){
        
        //create 모드에서 submit 버튼을 눌러 발동할 때 .concat 메소드를 이용하여 새로운 
        //contents의 요소를 생성하도록 설정하였다.
            this.max_content_id = this.max_content_id+1;
            var _contents = this.state.contents.concat(
           {id:this.max_content_id, title:_title, desc:_desc}
            )
            this.setState({ 
            
            //.setState 메소드로 .concat을 이용하여 만든 새로운 객체를 contents 에주입
                contents: _contents
            });
            
            console.log(_title, _desc);
        }.bind(this)}></CreateContent>
    }
    return (
      <div className="App">
        <Subject 
          title={this.state.subject.title} 
          sub={this.state.subject.sub}
          onChangePage={function(){
            this.setState({mode:'TEST1'});
          }.bind(this)}
        >
        </Subject>

        <TOC 
         onChangePage={function(id){
            this.setState({
              mode:'TEST2',
              selected_content_id:Number(id)
            });
          }.bind(this)} 
          data={this.state.contents}
        ></TOC>

        <Control onChangeMode={function(_mode){
                  this.setState({
                      mode:_mode
                  });
                 }.bind(this)}></Control>

        {_article}
      </div>
    );
  }
}
export default App;

create 모드에서 submit하자 새로운 contents가 생성되었다.

 

 

 

 

 

 

4. shouldComponentUpdate

 

TOC 부분의 컴포넌트 쪽에서 TOC 리스트들의 링크를 누르면 render()함수까지 실행되는 비효율적인 결과를 찾을 수 있다. 이를 해결하기 위해서는 shouldComponentUpdate()라는 메소드를 통해 이 문제를 해결할 수 있다.

 

 

TOC.js

import React, { Component } from 'react';

class TOC extends Component{
    shouldComponentUpdate(newProps, newState){ 
    // shouldComponentUpdate의 첫번째 인자는 create에 인해 props 값이 변화된 TOC 값을 받아내고
    // 두번째 인자는 값이 그대로인 것을 받아낸다.
        if(this.props.data === newProps.data){ 
        //그래서 if문을 통해 create에 인해 props 값이 변화된 TOC 값을 받아낼 때 false을 리턴하여 
        //불필요한 render()을 실행시키지 않도록 하였다.
            return false;
        }
        return true; //true일때는 그대로 render()가 실행된다.
    }
    render(){
      console.log('TOC render');
      var lists = [];
      var data = this.props.data;
      var i = 0;
      while(i < data.length){
        lists.push(
          <li key={data[i].id}>
            <a 
              href={"/content/"+data[i].id}
             
              onClick={function(id, e){
                e.preventDefault();
               
                this.props.onChangePage(id);
              }.bind(this, data[i].id)}
            >{data[i].title}</a>
          </li>);
        i = i + 1;
      }
      return (
        <nav>
            <ul>
                {lists}
            </ul>
        </nav>
      );
    }
  }
export default TOC;

 

 

 

 

 

 

 

 

반응형

'프로그래밍 개발 > ReactJs' 카테고리의 다른 글

ReactJs - JSX 기본  (0) 2021.01.05
ReactJs - Update , Delete기능 구현하기  (0) 2021.01.04
ReactJs - 이벤트  (0) 2020.12.31
ReactJs - state  (0) 2020.12.31
ReactJs - 컴포넌트 제작하기  (0) 2020.12.30

댓글