create 구현 [1] : mode 변경/전환

SPANKEEE·2023년 1월 12일
0

리액트-시작

목록 보기
21/30

컨트롤러(Control)

이전에 살펴본 생성 기능을 구현해보자.

우선 <Navi><Arti>사이에 create,update,delete라고 하는 세가지 mode로 진입하는 버튼을 만들자.

  • <Navi> 컴포넌트
<ul>
  <li><a href="/create">create</a></li>
  <li><a href="/update">update</a></li>
  <li><input type="button" value="delete">delete</input></li>
</ul>

create, upadeta, 그리고 read는 어떤 특정한 페이지로 이동해서 오퍼레이션이 실행 된다.

이러한 상황에서 delete 버튼을 클릭할 때 실제로 삭제가 일어나게 하는 경우에 링크를 쓰게 되면 문제가 발생할 수 있다.


예를 들어 어떤 사용자들이 페이지 방문을 할 때 좀 더 빨리 방문할 수 있게 미리 방문을 해 두는 소프트웨어가 깔려 있다면 delete로 되어 있는 부분도 미리 방문을 해버리게된다면? 삭제이벤트가 실행되는 문제가 있다.

따라서 delete 같은 경우는 링크 페이지 개념이 아니라 버튼과 같은 오퍼레이션 개념의 기능을 사용하도록 한다.

  • Control.js
import React, { Component } from 'react';
class Control extends Component {
  render() {
    return(
      <ul>
  		<li><a href="/create">create</a></li>
  		<li><a href="/update">update</a></li>
  		<li><input type="button" value="delete">delete</input></li>
	  </ul>
    );
  }
}
export default Control;

이렇게 만든 코드들을 <Control>라고 하는 컴포넌트로 만들어 외부의 Control.js파일로 만든다.

  • App.js
import Control from "./components/Control"; // 컴포넌트 불러오기
//`App.js > render` Navi컴포넌트의 밑에 배치
...
</Navi>
<Control></Control>
...

아까와 똑같아 보이지만 Control.js라는 파일로 분리시킨 것이다.


mode 변경 이벤트

<Control>에서 3개 중에 하나를 클릭했을 때 어떤 일이 일어나게 하기 위해서 onChangeMode라는 이벤트를 정의해준다.

이것은 이벤트가 실행 됐을 때 실행되어야 하는 함수인 이벤트 핸들러(Evenet Handler)를 설치하는 것이다.

링크를 클릭했을 때 onChangeMode라는 핸들러가 실행되게 하기 위해 <a> 태그에 onClick속성을 추가한다.

  • Control.js
import React, { Component } from 'react';
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 onClick={function(e){
          e.preventDefault();
          this.props.onChangeMode('delete');
        }.bind(this)} type="button" value="delete"></input></li>
      </ul>
    );
  }
}
export default Control;

onChange가 호출될 때 어떤 역할을 하는 링크인지 알 수 있도록 첫 번째 인자를 받을 수 있어야 한다.

mode라는 값으로 첫번째 인자를 받고 함수 안에서는 mode라는 변수로 현재 상태가 전달이 되게 된다.

onChangeMode함수가 호출될 때마다 앱 컴퍼넌트의 mode state값을 바꾸기 위해서는 setState() 함수를 사용한다.

  • App.js > render > Control 컴포넌트 영역
<Control onChangeMode={function (_mode) {
  this.setState({
    mode: _mode
  });
}.bind(this)</ Control>

이제 create를 클릭하면 mode의 값이 create로 바뀌고, update를 클릭하면 update, delete를 클릭하면 delete로 바뀌는 것을 확인할 수 있다.

현재 상태에 따라서 mode라는 state값이 바뀌게 된 것이다.

mode 전환 이벤트

이번에는 create를 클릭할 때 쓰기에 사용될 컴포넌트로 교체시키는 작업을 해보자.

현재 이 애플리케이션은 create를 클릭했을 때 <Arti>컴포넌트는 읽기에서 사용되는 컴포넌트다.
이번 시간에는 create를 클릭하면 쓰기에서 사용될 컴포넌트로 교체시키는 작업을 해보자.

이를 위해 기존에 있었던 읽기 컴퍼넌트 이름을 <ReadArti>로 수정한다.

<App> 컴포넌트의 mode의 값이 create 라면 <CreateArti> 컴포넌트 로 바뀌고

<App>컴포넌트에 mode의 값이 read라면 <ReadArti> 컴포넌트 로 바뀌도록 하자.

기존에 있던 <Arti> 컴포넌트 이름을 <ReadArti> 로 바꾸고 파일의 이름도 ReadArti.js 로 변경한다.

ReadArti.js

import ReadArti from "./components/ReadArti"
<ReadArti title = {_title} desc={_desc}</ReadArti>

이전파일과 똑같지만 이름이 좀 더 보기좋게 바뀌게 되었다.

ReadArti.js 와 마찬가지로 CreateArti.js 파일을 추가한다.
이 파일에서는 Form 을 구현할 것이다.

  • CreataeArti.js (기존 ReadArti.js 를 복사해서 수정)
import React, {Component} from 'react';
class CreateArti extends Component{
  render(){
    console.log("Arti Render");
    return(
      <article>
        <h2>Create</h2>
        <form>
      	  ...
        </form>
      </article>
    );
  }
}
export default CreateArti;
  • App.js
// App.js 파일에 import 추가
import CreateArti from "./components/CreateArti"

지금까지 수정 작업을 통해 <Control>에서 create 를 클릭하면 <App> 컴포넌트의 mode가 create로 바뀌게 된다.

이때 <ReadArti>가 있는 부분을 <CreateArti>로 교체하는 코드를 작성해보자.

App.js파일로 들어가 mode의 값에 따라 <article> 영역이 교체되는 코드를 <ReadArti>영역이 가변적으로 바뀔 수 있도록 하기 위해 _article이라는 변수로 처리한다.

App.js

render(){
  var _title, _desc, _article = null; // <- _article : 컴포넌트가 담길 변수
  if (this.state.mode === 'welcome') {
    _title = this.state.welcome.title;
    _desc = this.state.welcome.desc;
    _article = <ReadArti title = { _title } desc = { _desc }</ ReadArti>
  } 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;
  }
}
  • App.js > render > Control가 끝나는 컴포넌트 밑에
}.bind(this)}></Control> // Control 컴포넌트
{_article}	// 	최종적으로 content가 출력될 컴포넌트를 가진 변수

기존에 있었던 <ReadArti>_article 이라는 변수에 준 것이다.

그리고 mode가 read일 때도 <ReadArti>가 나오는건 마찬가지이기 때문에 else if 구문에도 추가해 준다.

위 코드를 통해 mode가 welcome이나 read인 경우에는 _article의 값이 <ReadArti>로 되게 된다.

그럼 그에 따라서 {_article} 부분에 <ReadArti> 가 나온다.
브라우저에서 링크를 클릭했을 때 <ReadArti> 가 잘 나오는 걸 확인할 수 있다.

다음으로 mode가 create일 때 <CreateArti>가 화면에 출력되도록 작성한다.

App.js

render(){
  var _title, _desc, _article = null; // <- _article : 컴포넌트가 담길 변수
  if (this.state.mode === 'welcome') {
    ...
  } else if (this.state.mode === 'read') {
    ...
  } else if (this.state.mode === 'create'){ // create 모드
    _article = <CreateArti></CreateArti>
  }
}
  • 결과

<App> 컴포넌트 mode가 create일 때 <ReadArti><CreateArti>로 바뀌게 된다.

웹 페이지에 <CreateArti><h2> 태그 부분이 Create로 잘 출력되는 것을 확인할 수 있다.

profile
해야되요

0개의 댓글