[React]생활코딩 7️⃣- update & delete

2 minute read

App.js 리팩토링

class App extends Component {
  constructor(props){
    super(props);
    this.max_content_id = 3;
    this.state = {
      mode:'read',
      selected_content_id:1,
      Subject: {title:'Web', sub:'World Wide Web!'},
      welcome: {title:'welcome', desc:'hello, React!!'},
      contents: [
        {id:1, title:'HTML', desc:'HTML is for information'},
        {id:2, title:'CSS', desc:'CSS is for design'},
        {id:3, title:'JavaScript', desc:'JavaScript is for interactive'}
      ]
    }
  }
  getReadContent(){
    var i = 0;
      while(i < this.state.contents.length){
        var data = this.state.contents[i];
        if(data.id === this.state.selected_content_id){
          return data;
        }
        i = i + 1 ;
      }
  }
  getContent(){
    var _title, _desc, _article = null;
    if(this.state.mode === 'welcome'){
      _title = this.state.welcome.title;
      _desc = this.state.welcome.desc;

      _article = <ReadContent title={_title} desc={_desc}></ReadContent>

    } else if(this.state.mode === 'read'){

      var _content = this.getReadContent();

      _article = <ReadContent title={_content.title} desc={_content.desc}></ReadContent>

    } else if(this.state.mode === 'create'){

      _article = <CreateContent onSubmit={function(_title, _desc) {
        
        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({
          contents : _contents
        });
        console.log(_title, _desc);
      }.bind(this)}></CreateContent>

    } else if(this.state.mode === 'update'){
      
      _content = this.getReadContent();
      _article = <UpdateContent data={_content} onSubmit={function(_title, _desc) {
        
        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({
          contents : _contents
        });
        console.log(_title, _desc);
      }.bind(this)}></UpdateContent>

    } else if(this.state.mode === 'delete'){

      _article = <DeleteContent></DeleteContent>

    }
    return _article;
  }
  render(){
    console.log('App render');
    
    return (
      <div className="App">
        <Subject 
        title={this.state.Subject.title} 
        sub={this.state.Subject.sub}
        onChangePage={function(){
          this.setState({mode : 'welcome'});
        }.bind(this)}>
        </Subject>
        <TOC 
        onChangePage={function(id){
          this.setState({
            mode:'read',
            selected_content_id:Number(id)
          });
        }.bind(this)}
        data={this.state.contents}>
        </TOC>
        <Control onChangeMode={function(_mode) {
          this.setState({
            mode : _mode
          });
        }.bind(this)}></Control>
        {this.getContent()}
      </div>
    );
  }
}
  • render() 함수내에서 mode에 따라 컴포넌트를 변경시켜주는 부분을 getContent( ) 함수로 분리시켜준다.
  • 선택된 id값과 일치하는 data를 가져오는 부분을 getReadContent( ) 함수로 분리시켜준다.

update 구현: form 작업

UpdateContent.js

import React, { Component } from 'react';

class UpdateContent extends Component{
    constructor(props){
      super(props);
      this.state = {
        title:this.props.data.title,
        desc:this.props.data.desc,
        id:this.props.data.id
      }
      this.inputFormHandler = this.inputFormHandler.bind(this);
    }
    inputFormHandler(e){
      this.setState({[e.target.name]:e.target.value});
    }
    render(){
      console.log('UpdateContent render');
      return (
        <article>
            <h2>Update</h2>
            <form action="/create_process" method="post"
              onSubmit={function(e){
                e.preventDefault();
                this.props.onSubmit(
                 this.state.id,
                 this.state.title,
                 this.state.desc
                );
              }.bind(this)}
            >
              <input type="hidden" name="id" value={this.state.id}></input>
              <p>
                <input 
                  type="text" 
                  name="title" 
                  placeholder="title"
                  value={this.state.title}
                  onChange={this.inputFormHandler}
                ></input>
                </p>
              <p>
                <textarea 
                  onChange={this.inputFormHandler} 
                  name="desc" 
                  placeholder="description" 
                  value={this.state.desc}></textarea>
              </p>
              <p>
                <input type="submit"></input>
              </p>
            </form>
        </article>
      );
    }
  }

export default UpdateContent;

  • input태그와 textarea태그에서 onChange 이벤트가 발생했을 때, 실행 할 inputFormHandler( )메소드를 constructor안에 선언한다
constructor(props){
      super(props);
      this.state = {
        title:this.props.data.title,
        desc:this.props.data.desc,
        id:this.props.data.id
      }
      this.inputFormHandler = this.inputFormHandler.bind(this); // UpdateContent가 로드될때 this를 binding
    }
    inputFormHandler(e){//constructor 외부에 함수 선언
      this.setState({[e.target.name]:e.target.value});
    }

APP.js

else if(this.state.mode === 'update'){
      _content = this.getReadContent();
      _article = <UpdateContent data={_content} onSubmit={
        function(_id, _title, _desc) {
        var _contents = Array.from(this.state.contents); //원본 배열을 유지하고, 원본을 복제한 배열 생성

        var i = 0;
        while(i < _contents.length){
          if(_contents[i].id === _id){
            _contents[i] = {id:_id, title:_title, desc:_desc};
            break;
          }
          i = i+1;
        }
        this.setState({
          contents : _contents,
          mode:'read'
        });
        console.log(_title, _desc);
      }.bind(this)}></UpdateContent>

}

  • UpdateContent 컴포넌트에서 넘어온 _id,_title,_desc를 받아 반복문을 이용해 contents 중 id 값이 _id와 일치하는 요소의 값에 각각 _title, _desc 를 대입해준다.

Delete 구현

  • 버튼을 눌렀을 때는, confirm창을 띄워서 사용자의 실수를 방지해준다.
  • splice( ) 메소드를 이용해 배열의 삭제할 요소를 삭제하고, 나머지 요소들로 setState 해준다.
<Control onChangeMode={function(_mode) {
          if(_mode === 'delete'){
            if(window.confirm("realy?")){
              var _contents = Array.from(this.state.contents);
              var i = 0;
              while(i < this.state.contents.length){
                if(_contents[i].id === this.state.selected_content_id){
                  _contents.splice(i,1);
                  break;
                }
                i = i + 1;
              }
              this.setState({
                mode:'welcome',
                contents:_contents
              });
              alert('deleted!');
            }
          } else {
            this.setState({
              mode : _mode
            });
          }
          
}.bind(this)}></Control>

Leave a comment