React (7) delete

2020-06-28

delete 구현

특정 content가 화면에 띄워지고 있는 상태에서
delete 버튼을 누르면 그 content가 바로 삭제되게끔 구현.

delete 버튼을 보면 onChangeMode라고 하는 props를 호출하고 있고,
인자로 ‘delete’라는 값을 전달하고 있다.

class Control extends Component {
  render() {
    return(
      <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 type="button" value="delete" onClick={function(e) {
            e.preventDefault();
            this.props.onChangeMode('delete');
          }.bind(this)}></input></li>
        </ul>
    );
  }
}

즉, onChangeMode props의 _mode 인자로 ‘delete’가 전달되면
‘삭제 작업이 시작되었다’ 라는 의미임.
따라서, _mode가 ‘delete’이면 삭제 작업을 진행하고,
아니면 그냥 create, update 페이지로 전환만 해주면 됨.

→ 우선 window.confirm()을 이용해서 진짜로 삭제할건지를 한 번 더 물어보고
true가 return되면 삭제를 진행한다.

content 중에 누구를 삭제할 건지는 selected_content_id를 이용해서 찾아낸다.

{/* App의 render */}
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>
      <Navigation 
        data={this.state.contents}
        onChangePage={function(id) {
          this.setState({mode:'read',
        selected_content_id: Number(id)});
        }.bind(this)}
      ></Navigation>
      {/* 요기서부터 */}
      <Control onChangeMode={function(_mode) {
        if(_mode === "delete") {
          if(window.confirm('really?')) {
            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);
                break;
              }
              i = i + 1;
            }
            this.setState({
              mode: "welcome",
              contents: _contents
            });
          }
        } else {
          this.setState({ mode : _mode });
        }
      }.bind(this)}></Control>
      {/* 요기까지 */}
      {this.getContent()}
    </div>
  );
}

역시나 원본을 해치지 않기 위해 Array.from을 사용.
삭제할 id를 가진 배열 요소를 찾아냈다면, splice를 이용해 제거해준다.
그리고 그 제거해 준 배열을 다시 setState를 사용해 원본에 넣어주면 됨.

bind(this)에 관한 팁

만약 this.inputFormHandler라는 함수가 있다고 치자.
(이벤트 핸들러를 꼭 익명함수로만 만들어야 하는 게 아니다.
별도의 함수로 만들 수도 있다)
근데, 얘는 component에서 사용되는 함수라서, 맨날 뒤에 .bind(this)를 계속 붙여줘야됨.
이게 귀찮으면, constructor에 다음과 같이 적어주자.

constructor(props) {
  super(props);
  this.inputFormHandler = this.inputForm.handler.bind(this);
}

이렇게 해주면, 다음부터는 this.inputFormHandler만 호출해줘도
this.inputFormHandler.bind(this)를 호출한 것과 동일한 효과.