[React] 생활코딩-6 Update, Delete구현

ji_silver·2020년 7월 6일
0

[React] 생활코딩

목록 보기
6/6
post-thumbnail

1.Update

  • Read기능, Create 기능 결합
  • components 디렉터리에 UpdateContents.js 파일 생성

App.js

import UpdateContent from './components/UpdateContent';

...

else if (this.state.mode === 'update') {
  _article = <UpdateContent 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>
}
  • render()함수 안 코드가 복잡하기 때문에 새로운 함수로 쪼개서 분리시켜보기
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 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) {
      // add content to this.state.contents
      this.max_content_id = this.max_content_id + 1;
      // this.state.contents.push(
      // {id:this.max_content_id, title:_title, desc:_desc}
      // );
      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') {
    _article = <UpdateContent 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>
  }
  return _article;
}
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>
      //getContent()를 쓰는 건 _article이기 때문에 
      {this.getContent()}
    </div>
  );
}
  • UpdateContent 컴포넌트 실행 시 입력값으로 현재 선택된 id에 해당되는 contents를 주입시키기
  • mode가 read일 때 하는 방법과 같아 코드가 중복되기 때문에 getReadContent() 함수 생성하여 코드 넣어 리팩토링 하기
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;
  }
}
...

else if (this.state.mode === 'read') {
  var _content = this.getReadContent();
  _article = <ReadContent title={_content.title} desc={_content.desc}></ReadContent>
} 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>
}

UpdateContent 컴포넌트의 data의 값을 _content를 주며 현재 id값을 찾는다.
(현재 id 기본값은 2번이기때문에 2번 contents 출력 )

2. form

UpdateContent.js

import React, { Component } from 'react';

class UpdateContent extends Component {
    constructor(props) {
        super(props);
        this.state = {
            id: this.props.id,
            title: this.props.data.title,
            desc: this.props.data.desc
        }
        this.inputFormHandler = this.inputFormHandler.bind(this);
    }
    inputFormHandler(e) {
        this.setState({ [e.target.name]: e.target.value });
        // state값을 동적으로 바꾸기 위해 setState 사용
        // e.target.value를 사용하면 현재 텍스트 값을 읽을 수 있음
    }
    render() {
        console.log(this.props.data);
        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} //props는 읽기전용이기 때문에 수정이 되지 않음 -> 가변적인 데이터 state화 시키기
                            onChange={this.inputFormHandler} // onChange함수는 변화가 일어났는지 탐지
                        ></input>
                    </p>
                    <p><textarea
                        onChange={this.inputFormHandler}
                        name="desc"
                        placeholder="description"
                        value={this.state.desc} // textarea의 내용은 value 사용
                    >
                    </textarea>
                    </p>
                    <p><input type="submit"></input></p>
                </form>
            </article>
        );
    }
}

export default UpdateContent;

3. state 변경

  • update, create로 새로운 값 입력 시 mode를 'read'로 바꾸기

App.js

...
else if (this.state.mode === 'create') {
  _article = <CreateContent onSubmit={function (_title, _desc) {
    this.max_content_id = this.max_content_id + 1;
    var _contents = Array.from(this.state.contents);
    _contents.push({ id: this.max_content_id, title: _title, desc: _desc });
    // var _contents = this.state.contents.concat(
    //   { id: this.max_content_id, title: _title, desc: _desc }
    // )
    this.setState({
      contents: _contents,
      mode: 'read',
      selected_content_id: this.max_content_id
    });
    console.log(_title, _desc);
  }.bind(this)}></CreateContent>
} 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); //state의 contents 배열 복제하여 새로운 배열 만들어짐
    var i = 0;
    while (i < _contents.length) {
      if (_contents[i].id === _id) { // _contents의 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>
}

4. Delete

App.js

...
<Control onChangeMode={function (_mode) {
  if (_mode === 'delete') {
    if (window.confirm('really?')) { // confirm() 실행 시 확인누르면 true, cancel 누르면 false
      var _contents = Array.from(this.state.contents);
      var i = 0;
      while (i < _contents.length) {
        if (_contents[i].id === this.state.selected_content_id) {
          _contents.splice(i, 1) // splice()는 (어디서부터, 어디까지)를 지울 것인지 구하는 함수
          break;
        }
        i = i + 1;
      }
      this.setState({
        mode: 'welcome',
        contents: _contents
      });
      alert('deleted!');
    }
  } else {
    this.setState({
      mode: _mode
    });
  }
}.bind(this)}></Control>

profile
🚧개발중🚧

0개의 댓글